a-b-street/abstreet · critical

You forgot to call initialize on SimFlags after parsing…

Error message

You forgot to call initialize on SimFlags after parsing from structopt

What it means

SimFlags::load_synchronously requires the `load` field (what map/scenario/save to load) to be non-empty. Structopt/CLI parsing cannot infer this value, so SimFlags::initialize must be called first to fill it; loading with an empty path is treated as programmer error and panics.

Solutions

  1. Call sim_flags.initialize(map_name) before load_synchronously
  2. Verify the CLI actually carries a --load value when not using defaults
  3. Use the intended UI loading path (SimFlags loading in map_gui) instead of the headless one

Example fix

// before
let flags = SimFlags::from_args();
flags.load_synchronously(&mut timer);
// after
let mut flags = SimFlags::from_args();
flags.initialize(map_name);
flags.load_synchronously(&mut timer);
Defensive patterns

Strategy: validation

Validate before calling

if flags.load.is_empty() {
    flags.initialize(map_name);
}
flags.load_synchronously(&mut timer);

Type guard

fn flags_ready(flags: &SimFlags) -> bool { !flags.load.is_empty() }

Try / catch

let result = std::panic::catch_unwind(|| flags.load_synchronously(&mut timer));

Prevention

When it happens

Trigger: Constructing SimFlags via structopt/Defaults and calling load_synchronously() without first invoking SimFlags::initialize (which populates `load` from the map name).

Common situations: Headless/binary tools and tests that build SimFlags manually and skip initialize; copy-pasted flag setup where the initialize call was dropped; web/UI code paths that never call this headless loader.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/aafcfd69f5a23ff9. Report an issue: GitHub.

Appendix: source

Thrown at sim/src/make/load.rs:75

    // TODO rename seattle_test
    pub fn for_test(run_name: &str) -> SimFlags {
        SimFlags {
            load_path: None,
            load: MapName::seattle("montlake").path(),
            scenario_modifiers: Vec::new(),
            rng_seed: SimFlags::RNG_SEED,
            opts: SimOptions::new(run_name),
        }
    }

    pub fn make_rng(&self) -> XorShiftRng {
        XorShiftRng::seed_from_u64(self.rng_seed)
    }

    /// Loads a map and simulation. Not appropriate for use in the UI or on web.
    pub fn load_synchronously(&self, timer: &mut abstutil::Timer) -> (Map, Sim, XorShiftRng) {
        if self.load.is_empty() {
            panic!("You forgot to call initialize on SimFlags after parsing from structopt");
        }

        let mut rng = self.make_rng();

        let mut opts = self.opts.clone();

        if self.load.starts_with(&abstio::path_player("saves/")) {
            info!("Resuming from {}", self.load);

            let sim: Sim = abstio::must_read_object(self.load.clone(), timer);

            let mut map = Map::load_synchronously(sim.map_name.path(), timer);
            match MapEdits::load_from_file(
                &map,
                abstio::path_edits(map.get_name(), &sim.edits_name),
                timer,
            ) {
                Ok(edits) => {

View on GitHub (pinned to 0964f29315)