{"record":{"id":"00cd1376009ef8b6","repo":"Hmbown/CodeWhale","slug":"failed-to-parse-config-at-file-contents-were-o","errorCode":null,"errorMessage":"failed to parse config at {}; file contents were omitted","messagePattern":"failed to parse config at (.+?); file contents were omitted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/config/src/config_document.rs","lineNumber":30,"sourceCode":"use anyhow::{Context, Result, bail};\n\nuse crate::{\n    checked_path_exists, normalize_config_file_path, persistence, read_checked_config_file,\n    write_one_time_config_backup,\n};\n\n/// Parse the latest document under the shared write lock, apply `mutate`, and\n/// atomically persist only the resulting delta.\npub fn mutate_config_document<T, F>(path: &Path, mutate: F) -> Result<T>\nwhere\n    F: FnOnce(&mut toml_edit::DocumentMut) -> Result<T>,\n{\n    with_config_write_lock(path, |path| {\n        let original = read_optional_config(path)?;\n        let mut document = match original.as_deref() {\n            Some(raw) if !raw.trim().is_empty() => {\n                raw.parse::<toml_edit::DocumentMut>().map_err(|_| {\n                    anyhow::anyhow!(\n                        \"failed to parse config at {}; file contents were omitted\",\n                        crate::quote_os_path(path)\n                    )\n                })?\n            }\n            _ => toml_edit::DocumentMut::new(),\n        };\n        heal_extras_nesting(&mut document);\n        let result = mutate(&mut document)?;\n        let body = document.to_string();\n        if original.as_deref() == Some(body.as_str()) || (original.is_none() && body.is_empty()) {\n            return Ok(result);\n        }\n        persist_locked(path, original.as_deref(), body.as_bytes())?;\n        Ok(result)\n    })\n}\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/config/src/config_document.rs#L12-L48","documentation":"`mutate_config_document` parses the existing config file as a TOML document before applying a mutation. If the file's contents are non-empty but not valid TOML, it aborts rather than risk destroying data. The message intentionally omits the file contents so secrets in the config are never echoed into logs.","triggerScenarios":"Any config mutation (API key revoke, targeted updates, lock-based writes) when `path` contains non-empty text that `toml_edit::DocumentMut` cannot parse.","commonSituations":"A manual edit broke TOML syntax (unclosed quote, bad table header), another tool wrote non-TOML content into the config, or a partially completed write left the file truncated mid-statement.","solutions":["Run `toml-lint`/`taplo check` or a TOML parser on the file at the path in the message to find the syntax error.","Fix the TOML syntax by hand (common culprits: unclosed strings, duplicate keys, malformed `[table]` headers).","If the file is unrecoverable, restore from backup or version control, then retry the command.","Do not paste the file contents into shared logs/issues — it may contain API keys."],"exampleFix":"// before (broken TOML)\nmodel = \"gpt-4o\n// after\nmodel = \"gpt-4o\"","handlingStrategy":"validation","validationCode":"// check TOML validity before any config mutation\nlet raw = std::fs::read_to_string(&path)?;\nif !raw.trim().is_empty() {\n    raw.parse::<toml_edit::DocumentMut>()\n        .map_err(|e| format!(\"config TOML invalid, fix before running commands: {e}\"))?;\n}","typeGuard":null,"tryCatchPattern":"match cmd.run() {\n    Err(e) if e.to_string().contains(\"failed to parse config\") => {\n        eprintln!(\"Fix the TOML file manually; contents not shown for safety.\");\n    }\n    other => other?,\n}","preventionTips":["Validate config TOML after every hand edit (taplo check or equivalent)","Keep the config file under version control to enable quick restore","Never point other tools' output at the config path"],"tags":["config","toml","parse-error"],"backgroundTag":"toml-parse-error","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}