Hmbown/CodeWhale · warning

load config store

Error message

load config store

What it means

ConfigStore::load(Some(config_path.clone())).expect("load config store") in the same test panics when loading the seeded config fails — invalid TOML, an IO error, or a schema validation error inside ConfigStore. This is the real signal when fixture content and the loader's expected schema drift.

Solutions

  1. Read the inner error in the panic: parse error -> fix the fixture TOML; missing field -> add #[serde(default)] or update the fixture.
  2. If a new required Config field was introduced, update test fixtures (or add a serde default) rather than bending the loader.
  3. Confirm config_path exists before load; keep the tempdir alive across the test.

Example fix

// before
let original = "# my model\nmodel = \"deepseek-v4-flash\"\n# end comment\n";
// after (new required field added to Config)
let original = "# my model\nmodel = \"deepseek-v4-flash\"\napi_key_env = \"KEY\"\n# end comment\n";
Defensive patterns

Strategy: validation

Validate before calling

// validate fixture before loading
let _probe: toml::Value = toml::from_str(original).expect("fixture must be valid TOML");

Try / catch

let store = ConfigStore::load(Some(config_path.clone()))
    .unwrap_or_else(|e| panic!("load config store failed: {e}; check fixture TOML vs Config schema"));

Prevention

When it happens

Trigger: The seeded TOML ("# my model\nmodel = \"deepseek-v4-flash\"\n# end comment\n") no longer parses or validates after a Config struct change (renamed/typed fields); the file was not written by the previous fixture step.

Common situations: Adding a required field to Config without a serde default breaks old fixtures; typo'd TOML in a hand-edited test string; config file path passed incorrectly to load.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/5bb6dfd8995e96a7. Report an issue: GitHub.

Appendix: source

Thrown at crates/config/src/tests.rs:4220

    )
    .expect("seed backup");

    scrub_plaintext_api_keys_from_config_backup(&path).expect("scrub backup");

    let backup = fs::read_to_string(backup_path).expect("read backup");
    assert!(!backup.contains("old-test-credential"), "{backup}");
    assert!(!backup.contains("api_key"), "{backup}");
    assert!(backup.contains("model = \"old-model\""));
}

#[test]
fn config_store_save_preserves_comments() {
    let dir = tempfile::tempdir().expect("tempdir");
    let config_path = dir.path().join(CONFIG_FILE_NAME);
    let original = "# my model\nmodel = \"deepseek-v4-flash\"\n# end comment\n";
    fs::write(&config_path, original).expect("write config");

    let mut store = ConfigStore::load(Some(config_path.clone())).expect("load config store");
    store.config.model = Some("deepseek-v4-pro".to_string());
    store.save().expect("save");

    let body = fs::read_to_string(&config_path).expect("read config");
    assert!(body.contains("# my model"), "prefix comment preserved");
    assert!(body.contains("# end comment"), "suffix comment preserved");
    assert!(body.contains("model = \"deepseek-v4-pro\""));
}

#[test]
fn config_store_save_preserves_disabled_keys() {
    let dir = tempfile::tempdir().expect("tempdir");
    let config_path = dir.path().join(CONFIG_FILE_NAME);
    fs::write(
        &config_path,
        "# my note\nmodel = \"deepseek-v4-flash\"\n# base_url = \"http://localhost:11434/v1\"\n",
    )
    .expect("write config");

View on GitHub (pinned to 433685b202)