Hmbown/CodeWhale · error

Could not parse configuration for route preference…

Error message

Could not parse configuration for route preference migration; contents omitted

What it means

migrate_legacy_route_preferences, invoked inside mutate_config_document, must deserialize the current TOML document into Config to compute and stamp migrated route preferences. If the document cannot be parsed, it aborts the whole mutation with this error; contents are omitted because the file may hold private text.

Solutions

  1. Fix the TOML so it deserializes as Config (validate syntax and field types)
  2. Restore a backup of config.toml or regenerate defaults, then retry the operation
  3. Identify offending keys by parsing config.toml with toml::from_str::<Config> in a scratch test and fixing reported fields

Example fix

# before
route_preference = "auto-pilot"  # no longer a valid value
# after
route_preference = "balanced"
Defensive patterns

Strategy: try-catch

Validate before calling

// before any mutate_config_document call
let raw = std::fs::read_to_string(&config_path)?;
toml::from_str::<Config>(&raw)?; // surfaces the real parse error early

Try / catch

match mutate_config_document(&path, migrator) {
    Err(e) if e.to_string().contains("route preference migration") => {
        eprintln!("config.toml unparseable; fix or restore before writing");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Any config write routed through mutate_config_document while the on-disk config document contains invalid TOML or values that fail Config deserialization (wrong types, unknown required fields).

Common situations: Corrupted or hand-edited config.toml; schema drift after an upgrade leaving keys with old types; partial writes from a previous crash.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/72ff10f96e5f9385. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/config_persistence.rs:50

/// Commit the legacy effective startup selection with its receipt in the same
/// atomic config write. Settings remains untouched, so an interrupted cleanup
/// or an older binary cannot erase the user's historical choices. After this
/// marker, Config never consults those legacy route fields again.
pub(crate) fn migrate_legacy_route_preferences(
    path: &Path,
    doc: &mut toml_edit::DocumentMut,
) -> anyhow::Result<()> {
    if !crate::config::is_home_config_path(path)
        || doc
            .get("route_preferences_version")
            .and_then(toml_edit::Item::as_integer)
            .is_some()
    {
        return Ok(());
    }
    let mut config: crate::config::Config = toml::from_str(&doc.to_string()).map_err(|_| {
        anyhow::anyhow!(
            "Could not parse configuration for route preference migration; contents omitted"
        )
    })?;
    let previous_config = config.clone();
    let settings =
        crate::settings::Settings::load_legacy_route_preferences_read_only().map_err(|_| {
            anyhow::anyhow!(
                "Could not read legacy route preferences; configuration was not changed"
            )
        })?;
    // An unparsable settings.toml loads as defaults carrying `load_error`, which
    // keeps the UI usable but is not evidence that no preferences were saved.
    // This migration is one-way: stamping the version over defaults would retire
    // the user's real legacy choices unread. Refuse instead, exactly as
    // `Settings::save_to_path` refuses to overwrite an unreadable document.
    // Contents stay omitted; the file may hold private text.
    anyhow::ensure!(
        settings.load_error.is_none(),

View on GitHub (pinned to 73e0f67d83)