BigPizzaV3/CodexPlusPlus · error

config.toml TOML parse failed: {error}

Error message

config.toml TOML parse failed: {error}

What it means

Thrown by parse_toml_document in crates/codex-plus-core/src/plugin_marketplace.rs when the config.toml text it is asked to edit cannot be parsed by toml_edit. The function is tolerant of a leading UTF-8 BOM (stripped via trim_start_matches('\u{feff}')) and of empty/whitespace-only files (those yield a fresh empty document), so this error means genuine TOML syntax errors: unclosed strings or tables, duplicate keys, or malformed inline values. The {error} placeholder carries toml_edit's message, which includes the line/column of the offending token.

Source

Thrown at crates/codex-plus-core/src/plugin_marketplace.rs:732

}

fn windows_extended_path(path: &Path) -> String {
    let value = path.to_string_lossy();
    if value.starts_with(r"\\?\") {
        value.into_owned()
    } else {
        format!(r"\\?\{value}")
    }
}

fn parse_toml_document(contents: &str) -> anyhow::Result<DocumentMut> {
    let contents = contents.trim_start_matches('\u{feff}');
    if contents.trim().is_empty() {
        Ok(DocumentMut::new())
    } else {
        contents
            .parse::<DocumentMut>()
            .map_err(|error| anyhow::anyhow!("config.toml TOML parse failed: {error}"))
    }
}

fn table_mut_or_insert<'a>(doc: &'a mut DocumentMut, key: &str) -> anyhow::Result<&'a mut Table> {
    if !doc.as_table().contains_key(key) {
        doc[key] = toml_edit::table();
    }
    if doc.get(key).and_then(Item::as_table).is_none() {
        doc[key] = toml_edit::table();
    }
    doc.get_mut(key)
        .and_then(Item::as_table_mut)
        .ok_or_else(|| anyhow::anyhow!("{key} must be a TOML table"))
}

fn ensure_trailing_newline(mut contents: String) -> String {
    if !contents.ends_with('\n') {
        contents.push('\n');

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. Read the {error} suffix: toml_edit reports the exact line and column — open config.toml and fix the syntax at that position
  2. Validate the file externally before retrying, e.g. cargo toml2json or python -c "import tomllib;tomllib.load(open('config.toml','rb'))" to confirm it parses
  3. Remove merge-conflict markers and duplicate table/key definitions, and quote any value containing special characters
  4. If the file is unrecoverable, restore from the backup the tool writes next to it (or regenerate the file) instead of editing the broken one

Example fix

# before (config.toml, broken TOML)
model = gpt-5  # unquoted value with a dash
[profiles.x
key = "unterminated

# after
model = "gpt-5"
[profiles.x]
key = "terminated"
Defensive patterns

Strategy: validation

Validate before calling

fn config_toml_parses(path: &Path) -> bool {
    let text = std::fs::read_to_string(path)
        .unwrap_or_default()
        .trim_start_matches('\u{feff}')
        .to_string();
    text.trim().is_empty()
        || text.parse::<toml_edit::DocumentMut>().is_ok()
}

Try / catch

let doc = parse_toml_document(&contents)
    .with_context(|| format!("config.toml is invalid — fix the syntax at the reported line, or restore {}", path.display()))?;

Prevention

When it happens

Trigger: Calling the marketplace/config writer on a hand-edited ~/.codex/config.toml that contains a syntax error (e.g. an unterminated string, a duplicate [profiles.x] header, or a bare value like key = no-quotes); feeding config.toml content that was mangled by a merge conflict; a file truncated mid-write by a crash.

Common situations: Users hand-editing config.toml and introducing typos; git merge conflict markers (<<<<<<<) left in the file; third-party tools rewriting config.toml in a non-TOML-conformant way; CRLF or smart-quote characters pasted from rich-text editors.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16). Data as JSON: /api/errors/b304c1c7a9f7af41. Report an issue: GitHub.