{"record":{"id":"60d2fe27ce3afbef","repo":"xai-org/grok-build","slug":"refusing-to-overwrite-unparseable-fix-the","errorCode":null,"errorMessage":"refusing to overwrite unparseable {}: {}; fix the syntax before retrying","messagePattern":"refusing to overwrite unparseable (.+?): (.+?); fix the syntax before retrying","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/util/config/mcp.rs","lineNumber":792,"sourceCode":"    let is_user = path == config_path().as_path();\n    let _guard = if is_user {\n        Some(super::persist::lock_config_writes().await)\n    } else {\n        None\n    };\n\n    let original = match tokio::fs::read_to_string(path).await {\n        Ok(s) => s,\n        Err(e) if e.kind() == std::io::ErrorKind::NotFound && is_user => String::new(),\n        Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(false),\n        Err(e) => {\n            return Err(anyhow::anyhow!(\"failed to read {}: {e}\", path.display()));\n        }\n    };\n    let mut root = match super::persist::parse_existing_config_toml(&original) {\n        Ok(v) => v,\n        Err(parse_err) => {\n            return Err(anyhow::anyhow!(\n                \"refusing to overwrite unparseable {}: {}; fix the syntax before retrying\",\n                path.display(),\n                parse_err\n            ));\n        }\n    };\n    let before = toml::to_string_pretty(&root)?;\n    let table = root\n        .as_table_mut()\n        .ok_or_else(|| anyhow::anyhow!(\"config root is not a table\"))?;\n    f(table);\n    let toml_str = toml::to_string_pretty(&root)?;\n    if before == toml_str {\n        return Ok(false);\n    }\n    super::persist::atomic_write_string(path, &toml_str)\n        .map_err(|e| anyhow::anyhow!(\"failed to write {}: {e}\", path.display()))?;\n    Ok(true)","sourceCodeStart":774,"sourceCodeEnd":810,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/util/config/mcp.rs#L774-L810","documentation":"write_toml_table_if_changed refuses to rewrite a config file whose contents cannot be parsed as TOML, protecting hand-edited or corrupted configs from being clobbered by a generated write. The error carries both the path and the parse error and instructs the user to fix the syntax first.","triggerScenarios":"Calling save_mcp_server_enabled_in / save_user_mcp_server_enabled when parse_existing_config_toml fails on the existing file — i.e. the file exists but contains invalid TOML.","commonSituations":"A manual edit left a syntax error (unclosed string, bad table header, duplicate keys the parser rejects); a partially written file from an earlier crash; a non-TOML file placed at the config path.","solutions":["Open the file at the reported path, fix the TOML syntax error shown after the semicolon, then retry the save.","Keep a backup: copy the file aside, delete it so the tool writes a clean one, and re-apply settings manually.","Validate with a TOML parser/linter (`cargo add toml` one-off script or an editor TOML plugin) before retrying.","Check for duplicate/conflicting keys or a truncated file if the parse error is cryptic."],"exampleFix":"# before (invalid TOML)\n[mcp_servers]\nname = \"x\n# after (fixed)\n[mcp_servers.x]\ncommand = \"npx\"\nargs = [\"-y\", \"server\"]","handlingStrategy":"validation","validationCode":"fn toml_parses(path: &Path) -> Result<(), String> {\n    let s = std::fs::read_to_string(path).map_err(|e| e.to_string())?;\n    s.parse::<toml::Value>().map(|_| ()).map_err(|e| e.to_string())\n}\n// guard: if toml_parses(&cfg_path).is_err() { fix syntax before saving }","typeGuard":null,"tryCatchPattern":"match save_mcp_server_enabled_in(&cfg_path, name, enabled).await {\n    Err(e) if e.to_string().contains(\"refusing to overwrite unparseable\") => {\n        let backup = cfg_path.with_extension(\"toml.bak\");\n        std::fs::copy(&cfg_path, &backup)?; // preserve user edits\n        eprintln!(\"fix TOML syntax in {} (backup at {})\", cfg_path.display(), backup.display());\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["Run a TOML linter/parser after every manual config edit","Keep backups (.bak) before programmatic config rewrites","Never paste non-TOML content into the config path","Watch for truncated writes from crashes; the guard prevents silent data loss"],"tags":["rust","toml","config","parse-error","data-protection"],"backgroundTag":"unparseable-config-file","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}