{"record":{"id":"5d5e7acae8ac88ee","repo":"Hmbown/CodeWhale","slug":"could-not-parse-switched-route-contents-omitted","errorCode":null,"errorMessage":"Could not parse switched route; contents omitted","messagePattern":"Could not parse switched route; contents omitted","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/config_persistence.rs","lineNumber":278,"sourceCode":"    // route's leftovers.\n    if incoming.provider == ApiProvider::Custom && incoming.persisted_id().is_none() {\n        return Ok(());\n    }\n    // Only `default_text_model` is read here. The legacy root `model` key is\n    // never what blocks a load: `Config::default_model` already refuses to\n    // route a foreign legacy value to a provider that cannot serve it, and\n    // `Config::validate` does not consult it, so relocating it would move a\n    // value nothing is asking about.\n    const ROOT_KEY: &str = \"default_text_model\";\n    let Some(value) = doc\n        .get(ROOT_KEY)\n        .and_then(toml_edit::Item::as_str)\n        .map(str::to_owned)\n    else {\n        return Ok(());\n    };\n    let switched: crate::config::Config = toml::from_str(&doc.to_string())\n        .map_err(|_| anyhow::anyhow!(\"Could not parse switched route; contents omitted\"))?;\n    // `Config::validate` is the single authority on what the incoming route can\n    // serve, so a writer cannot disagree with the loader. Act only when this\n    // alias is what the loader rejects: a document already broken for an\n    // unrelated reason is not this writer's to rewrite.\n    let mut without_alias = switched.clone();\n    without_alias.default_text_model = None;\n    if switched\n        .provider_config_for(incoming.provider)\n        .and_then(|entry| entry.model.as_deref())\n        .is_some()\n        || switched.validate().is_ok()\n        || without_alias.validate().is_err()\n    {\n        return Ok(());\n    }\n    // An empty or control-bearing alias names no saved model. Nothing to\n    // relocate, and clearing it loses nothing.\n    if value.trim().is_empty() || value.chars().any(char::is_control) {","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/config_persistence.rs#L260-L296","documentation":"reconcile_root_model_aliases re-parses the mutated document as Config to decide whether the root default_text_model alias is servable by the incoming route; if that re-parse fails the writer aborts with this error rather than rewriting a config it cannot validate. Contents are omitted from the message intentionally, and the writer never touches a document broken for unrelated reasons.","triggerScenarios":"After persist_provider_selection's document mutation, the serialized document no longer deserializes into Config (e.g. a route-specific model value written with an invalid shape) when reconcile_root_model_aliases parses the switched document.","commonSituations":"A route model string or route table written by a buggy or older writer makes the config fail validation; another process rewrote config.toml mid-switch.","solutions":["Inspect config.toml for the route/model entries just written and fix or remove the invalid value.","Re-run the switch from a known-good config; check for a partially mutated file since the atomic writer should not have committed.","Update Codewhale if a released writer produced a shape the current Config type rejects (writer/loader version mismatch)."],"exampleFix":"# before (route section with bad value)\n[route]\ntext_model = \"\"\n# after\n[route]\ntext_model = \"claude-sonnet-4\"","handlingStrategy":"try-catch","validationCode":"let switched: Result<Config, _> = toml::from_str(&doc.to_string());\nif switched.is_err() { eprintln!(\"post-mutation document no longer loadable; aborting alias reconcile\"); }","typeGuard":null,"tryCatchPattern":"match persist_provider_selection(&path, p, ident, model) {\n    Err(e) if e.to_string().contains(\"Could not parse switched route\") => {\n        // inspect config.toml for values written by an older/buggy writer\n    }\n    other => other?,\n}","preventionTips":["Run the same Codewhale version for writing and loading configs.","Validate the config after each writer change with a parse round-trip test.","Do not edit route tables by hand while a switch is in flight."],"tags":["config","toml","parsing","rust"],"backgroundTag":"schema-validation-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}