Hmbown/CodeWhale · error

Could not parse route configuration; contents omitted

Error message

Could not parse route configuration; contents omitted

What it means

parse_config deserializes the route-preferences TOML file with toml::from_str. On any TOML syntax or structure error it raises this message, deliberately omitting the file contents so sensitive route/provider details never leak into logs. Callers like saved_config, prepare_document, and model_slot_for_document all depend on a fully parseable Config.

Solutions

  1. Open the route preferences file and fix the TOML syntax error; toml error positions are omitted here, so validate the file with a TOML linter or `toml::from_str` in a scratch test.
  2. Back up the file, delete it (or restore from backup) and let the app regenerate defaults.
  3. Check for legacy keys from an older version and rename/remove them to match the current Config struct.
  4. Verify the file is not truncated or being written concurrently; retry after the writer finishes.

Example fix

// before (broken TOML in route preferences)
[route]
model = "gpt-4o

// after
[route]
model = "gpt-4o"
Defensive patterns

Strategy: validation

Validate before calling

fn is_parseable_route_config(body: &str) -> bool {
    body.parse::<toml::Table>().is_ok()
}

Type guard

fn is_valid_toml(body: &str) -> Result<toml::Table, toml::de::Error> {
    toml::from_str(body)
}

Try / catch

match parse_config(&body) {
    Ok(config) => apply(config),
    Err(_) => eprintln!("route config TOML invalid; restore or fix the file"),
}

Prevention

When it happens

Trigger: Reading crates/tui route preferences file (e.g. via saved_config or prepare_document) when the TOML body has a syntax error, an unknown/misspelled key, or a value of the wrong type; also hit by model_slot_for_document, scrub_root_model_aliases_for_export, set_document, and unset whenever the same file fails to deserialize.

Common situations: A hand-edited or partially written route preferences file, an older/legacy config with fields no longer matching the Config schema, a truncated file from an interrupted save, or an editor inserting invalid TOML (bad quoting, duplicate keys, tabs).

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at crates/tui/src/route_preferences.rs:28

use crate::config_persistence as persistence;

/// Whether a config key names a provider or model selection.
pub fn is_route_key(key: &str) -> bool {
    matches!(
        key,
        "provider" | "model" | "default_model" | "default_text_model"
    ) || provider_model_id(key).is_some()
}

fn provider_model_id(key: &str) -> Option<&str> {
    key.strip_prefix("providers.")?
        .strip_suffix(".model")
        .filter(|id| !id.is_empty())
}

fn parse_config(body: &str) -> Result<Config> {
    toml::from_str(body)
        .map_err(|_| anyhow::anyhow!("Could not parse route configuration; contents omitted"))
}

fn model_identity(config: &Config, key: &str) -> Result<ProviderIdentity> {
    if key == "default_model" {
        let provider = if config.api_provider() == ApiProvider::DeepseekCN {
            ApiProvider::DeepseekCN
        } else {
            ApiProvider::Deepseek
        };
        config.resolve_provider_pin_identity(provider.as_str())
    } else if let Some(id) = provider_model_id(key) {
        // Leaf keys name TOML tables, whose canonical spelling can differ
        // from the public provider selector. Exact custom tables still win.
        let selector = if config
            .providers
            .as_ref()
            .and_then(|providers| providers.custom_provider_config(id))
            .is_some()

View on GitHub (pinned to 73e0f67d83)