Hmbown/CodeWhale · error
failed to parse config at
Error message
failed to parse config at {}; file contents were omitted What it means
`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.
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.
Example fix
// before (broken TOML) model = "gpt-4o // after model = "gpt-4o"
Defensive patterns
Strategy: validation
Validate before calling
// check TOML validity before any config mutation
let raw = std::fs::read_to_string(&path)?;
if !raw.trim().is_empty() {
raw.parse::<toml_edit::DocumentMut>()
.map_err(|e| format!("config TOML invalid, fix before running commands: {e}"))?;
} Try / catch
match cmd.run() {
Err(e) if e.to_string().contains("failed to parse config") => {
eprintln!("Fix the TOML file manually; contents not shown for safety.");
}
other => other?,
} Prevention
- 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
When it happens
Trigger: Any config mutation (API key revoke, targeted updates, lock-based writes) when `path` contains non-empty text that `toml_edit::DocumentMut` cannot parse.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Could not parse configuration for route preference…
- Could not parse destination route identity; contents omitted
- failed to parse config at
- failed to parse config at
- Failed to parse config file
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/00cd1376009ef8b6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/config_document.rs:30
use anyhow::{Context, Result, bail};
use crate::{
checked_path_exists, normalize_config_file_path, persistence, read_checked_config_file,
write_one_time_config_backup,
};
/// Parse the latest document under the shared write lock, apply `mutate`, and
/// atomically persist only the resulting delta.
pub fn mutate_config_document<T, F>(path: &Path, mutate: F) -> Result<T>
where
F: FnOnce(&mut toml_edit::DocumentMut) -> Result<T>,
{
with_config_write_lock(path, |path| {
let original = read_optional_config(path)?;
let mut document = match original.as_deref() {
Some(raw) if !raw.trim().is_empty() => {
raw.parse::<toml_edit::DocumentMut>().map_err(|_| {
anyhow::anyhow!(
"failed to parse config at {}; file contents were omitted",
crate::quote_os_path(path)
)
})?
}
_ => toml_edit::DocumentMut::new(),
};
heal_extras_nesting(&mut document);
let result = mutate(&mut document)?;
let body = document.to_string();
if original.as_deref() == Some(body.as_str()) || (original.is_none() && body.is_empty()) {
return Ok(result);
}
persist_locked(path, original.as_deref(), body.as_bytes())?;
Ok(result)
})
}
View on GitHub (pinned to 73e0f67d83)