Hmbown/CodeWhale · error

Could not parse destination route; contents omitted

Error message

Could not parse destination route; contents omitted

What it means

persist_provider_selection parses the destination config.toml into Config before mutating it; if the TOML is not a loadable Config (parse or validation failure) the mutation is aborted with this error, deliberately omitting file contents from the message. It makes route switching atomic: an unloadable config is never partially rewritten.

Solutions

  1. Open config.toml and fix the TOML syntax/type errors so it parses as Config, then retry the switch.
  2. Restore a known-good backup of config.toml or use the legacy-custom migration path the tests exercise.
  3. Back up the file, trim the offending sections, and re-run persist_provider_selection.

Example fix

# before (config.toml)
default_text_model = 123
# after
default_text_model = "claude-sonnet-4"
Defensive patterns

Strategy: validation

Validate before calling

let raw = std::fs::read_to_string(&path)?;
let cfg: Result<Config, _> = toml::from_str(&raw);
if cfg.is_err() {
    eprintln!("config.toml is unloadable; fix it before switching routes");
}

Try / catch

match persist_provider_selection(&path, provider, identity, model) {
    Err(e) if e.to_string().starts_with("Could not parse destination route") => {
        // surface file health problem to the user; do not overwrite
    }
    other => other?,
}

Prevention

When it happens

Trigger: persist_provider_selection is called while the destination config.toml fails to deserialize into crate::config::Config (wrong types, unknown fields, or values rejected by validation).

Common situations: The config file was hand-edited or written by another tool with incompatible fields; a legacy config shape that no longer deserializes; a partially-written config from a previous crash.

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@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a6043df3da6814b7. Report an issue: GitHub.

Appendix: source

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

            .metadata()
            .context("provider config metadata")?
            .provider_config_key()
            .to_string()
    };
    set_document_value(doc, &["providers", &provider_key, "model"], model)
}

/// One persistent owner and atomic write for an explicitly saved route.
pub(crate) fn persist_provider_selection(
    config_path: Option<&Path>,
    provider: ApiProvider,
    provider_identity: &str,
    model: Option<&str>,
) -> anyhow::Result<PathBuf> {
    let path = config_toml_path(config_path)?;
    mutate_config_document(&path, |doc| {
        let config: crate::config::Config = toml::from_str(&doc.to_string())
            .map_err(|_| anyhow::anyhow!("Could not parse destination route; contents omitted"))?;
        let identity = config
            .resolve_provider_pin_identity(provider_identity)
            .map_err(anyhow::Error::msg)?;
        anyhow::ensure!(
            identity.provider == provider,
            "The destination config has a different provider identity"
        );
        if let Some(model) = model {
            set_provider_model_document(
                doc,
                provider,
                identity.persisted_id().unwrap_or(&identity.key),
                model,
            )?;
        }
        set_document_value(
            doc,
            &["provider"],

View on GitHub (pinned to 73e0f67d83)