{"record":{"id":"1bc9654d6b2f9469","repo":"a-b-street/abstreet","slug":"impossible-to-start-from-a-non-sane-situation","errorCode":null,"errorMessage":"impossible to start from a non-sane situation.","messagePattern":"impossible to start from a non-sane situation\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sim/src/pandemic/mod.rs","lineNumber":327,"sourceCode":"                }\n            }\n            Self::Recovered(t) => Some(Self::Recovered(t)),\n            Self::Dead(t) => Some(Self::Dead(t)),\n        }\n    }\n\n    // TODO: not sure if we want an option here... I guess here we want because we could have\n    pub fn start(self, now: AnyTime, overlap: Duration, rng: &mut XorShiftRng) -> Result<Self> {\n        // rewrite this part with it\n        match self {\n            Self::Sane((ev, t)) => {\n                if overlap >= Self::get_time_exp(State::R_0 / State::T_INF, rng) {\n                    Ok(ev.next(now, rng))\n                } else {\n                    Ok(Self::Sane((ev, t)))\n                }\n            }\n            _ => bail!(\"impossible to start from a non-sane situation.\",),\n        }\n    }\n}\n","sourceCodeStart":309,"sourceCodeEnd":331,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/sim/src/pandemic/mod.rs#L309-L331","documentation":"The pandemic model's start() initializes each person's state by pattern-matching on an expected initial variant; only the sane initial state (with its event/time) can begin the simulation. Any other variant at startup — meaning the model was seeded with an impossible or uninitialized person state — bails with this fixed message. It is an internal invariant check on the SIR-state machine's starting conditions.","triggerScenarios":"Calling Simulator::start (sim/src/pandemic/mod.rs:327, invoked by initialize) when a person's initial state is anything other than the expected Sane((event, time)) variant — e.g. the RNG/seed produced a state outside the handled match arms, or initialization constructed persons incorrectly.","commonSituations":"Custom initial-condition modifications to the pandemic model, mismatched state enum after refactoring, or seeded RNG paths not covered by the initialization logic.","solutions":["Ensure all persons are initialized to the sane initial state (event plus sampled time) before calling start.","Check initialization code that constructs the initial person states for gaps/uninitialized variants.","If a new initial state was added, extend the match in start() to handle it.","Try a different RNG seed to confirm whether the failure is seed-specific or structural."],"exampleFix":"// before: person starts in an exotic variant\nlet init = Self::Infected; // not handled\n// after\nlet init = Self::Sane((initial_event, now));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn starts_sane(s: &PersonState) -> bool {\n    matches!(s, PersonState::Sane(_))\n}","tryCatchPattern":"match sim.start(now, &mut rng) {\n    Err(e) if e.to_string().contains(\"non-sane situation\") => {\n        // re-initialize all persons to Sane((event, time)) and retry\n    }\n    other => other?,\n}","preventionTips":["Always seed every person with the sane initial state before start().","Extend start()'s match when adding new initial-state variants.","Cover initialization across several RNG seeds in tests to catch uncovered branches."],"tags":["simulation","pandemic","state-machine","initialization"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}