{"record":{"id":"9266f6077259d90e","repo":"Hmbown/CodeWhale","slug":"config-entry-dotted-must-be-a-string","errorCode":null,"errorMessage":"config entry {dotted:?} must be a string","messagePattern":"config entry (.+?) must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/config_bundles.rs","lineNumber":1194,"sourceCode":"        (\"plugins\", &bundle.plugins),\n        (\"project\", &bundle.project),\n        (\"global\", &bundle.global),\n    ] {\n        if !section_applies(section, scope) {\n            continue;\n        }\n        for (key, value) in &table.entries {\n            let dotted = format!(\"{section}.{key}\");\n            if nonportable_path_reason(key).is_some()\n                || value_rejection_reason(key, value).is_some()\n            {\n                bail!(\"refusing to import non-portable config path {dotted}\");\n            }\n            if key == \"provider\" {\n                selected_provider = Some(\n                    value\n                        .as_str()\n                        .ok_or_else(|| anyhow!(\"config entry {dotted:?} must be a string\"))?,\n                );\n                continue;\n            }\n            collect_model_edits(&dotted, key, value, &mut model_edits)?;\n            if codewhale_tui::route_preferences::is_route_key(key) {\n                continue;\n            }\n            apply_config_value(&mut candidate, key, value)?;\n        }\n    }\n    document = toml::to_string(&toml::Value::Table(config_document(&candidate)?))?\n        .parse()\n        .map_err(|_| anyhow!(\"could not prepare imported configuration; contents omitted\"))?;\n    // Definitions precede the exact final selector. Root aliases then target\n    // that selected route, so an old provider slot cannot mask an imported model.\n    if let Some(provider) = selected_provider {\n        codewhale_tui::route_preferences::set_document(\n            store.path(),","sourceCodeStart":1176,"sourceCodeEnd":1212,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/config_bundles.rs#L1176-L1212","documentation":"prepare_import processes each config entry from the bundle; the special key 'provider' (the selected provider selector) must be a TOML string because it names a provider identity that is restored into route preferences. If the bundle contains provider as a non-string TOML value (integer, table, boolean), the import refuses with this message rather than guessing.","triggerScenarios":"Importing a bundle whose TOML body sets provider = 123, provider = true, or provider = { ... } instead of a string, during run_import / apply_bundle / dry-run planning.","commonSituations":"Hand-edited or machine-generated bundle files with a mistyped provider value; schema drift between bundle producers and consumers.","solutions":["Edit the bundle TOML so provider is a quoted string: provider = \"openai\".","Remove the provider key entirely if no provider should be selected.","Regenerate the bundle from a working export instead of hand-authoring it.","Validate the bundle's provider entry type before importing."],"exampleFix":"// before (bundle body)\nprovider = 42\n// after (bundle body)\nprovider = \"openai\"","handlingStrategy":"validation","validationCode":"let doc: toml::Value = toml::from_str(&bundle_body)?; if let Some(p) = doc.get(\"provider\") { if !p.is_str() { bail!(\"provider must be a string in bundle\"); } }","typeGuard":"fn provider_is_string(doc: &toml::Value) -> bool { doc.get(\"provider\").map_or(true, toml::Value::is_str) }","tryCatchPattern":"if let Err(e) = prepare_import(...) { if e.to_string().contains(\"must be a string\") { eprintln!(\"fix provider value type in bundle TOML\"); } }","preventionTips":["Always author provider as a quoted string in bundles.","Regenerate bundles via export, not by hand.","Type-check bundle values before import.","Keep producer and consumer schemas in sync."],"tags":["toml","config","validation"],"backgroundTag":"config-type-mismatch","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}