Skip to content

NonPerfAssumption constructed with missing fields in wrapRunPoolType (fields become undefined) #353

Closed

Description

@yellowbean

Location app/Main.hs:149-156 (wrapRunPoolType), type in src/Assumptions.hs:136-148

Cause Each equation builds AP.NonPerfAssumption{AP.interest = mRates} and omits 11 fields (stopRunBy, projectedExpense, callWhen, revolving, inspectOn, buildFinancialReport, pricing, fireTrigger, makeWholeWhen, issueBondSchedule, refinance). Haskell initializes omitted record fields to undefined; accessing any of them throws.

Evidence (GHC 9.12.3, -Wall) 8 × -Wmissing-fields at app/Main.hs:149-156, listing exactly those fields.

Impact Any pool-run path that reads a non-interest field (e.g. revolving) crashes with Prelude.undefined.

Suggested fix Populate all fields (use Nothing for the optionals), e.g. via a total defaultNonPerfAssumption value.

Activity

  1. yellowbean commented on Oct 20, 2026

    @yellowbean
    CollaboratorAuthor

    Fixed by 5193636 (merged in 8cfe4b7 / Sep26 #322), released in 0.52.14.

    What changed

    • src/Assumptions.hs:156-174: added total constructors defaultNonPerfAssumption (all 12 fields explicitly Nothing) and nonPerfWithRates mRates (record-update over the default), both exported.
    • app/Main.hs:156-164: all 8 wrapRunPoolType equations now build the assumption via AP.nonPerfWithRates mRates; the partial AP.NonPerfAssumption{AP.interest = mRates} syntax is gone.
    • Same class of bug fixed for RunContext: D.defaultRunContext added in src/Deal/DealBase.hs:219-220, replacing all-undefined RunContext {} uses.
    • Hastructure.cabal: -Werror=missing-fields enabled on library, executable and test suite, so future partial record construction fails the build.
    • Regression tests: nonPerfAssumptionTest in test/UT/DealTest.hs:521-539 forces show on every field of the defaults, so any residual undefined throws.

    Risk / perf / API

    • Behaviour-preserving: the pre-fix code only set interest, so pool-run cashflows are unchanged; Nothing is the documented meaning of the other optionals.
    • Negligible cost (one record per pool run, same allocation as before).
    • No request/response JSON or API change; only additive library exports.

    Verification (GHC 9.12.3)

    • cabal build lib:Hastructure exe:Hastructure-exe passes with -Werror=missing-fields.
    • cabal test Hastructure-test --test-options="-p NonPerfAssumption": 5/5 tests pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions