xai-org/grok-build · error

refusing to write import marker: existing config at {} is no

Error message

refusing to write import marker: existing config at {} is not valid TOML ({}). Fix the file (or move it aside) and retry.

What it means

write_import_marker refuses to add the claude_compat.imported marker when the existing config file fails TOML parsing. Rewriting the file would drop unrelated sections ([model], [ui], etc.) from a hand-edited config, so the error surfaces the parse failure and asks the user to fix the TOML first.

Source

Thrown at crates/codegen/xai-grok-shell/src/claude_import.rs:616

        .get("claude_compat")
        .and_then(|v| v.get("imported"))
        .and_then(|v| v.as_bool())
        .unwrap_or(false)
}

/// Write `[claude_compat] imported = true` to `~/.grok/config.toml`.
///
/// Uses the same atomic write pattern as `save_mcp_server_config` (write to
/// `.tmp`, then rename). Creates the file and parent directory if missing.
/// Existing content in the file is preserved.
fn write_import_marker(config_path: &Path) -> anyhow::Result<()> {
    // Surface parse errors instead of silently discarding the file: an atomic
    // rewrite would otherwise drop unrelated sections ([model], [ui], etc.)
    // and overwrite a hand-edited config that just happens to have a trailing
    // comma. The user can fix the TOML and retry.
    let mut root: TomlValue = match std::fs::read_to_string(config_path) {
        Ok(s) => toml::from_str(&s).map_err(|e| {
            anyhow::anyhow!(
                "refusing to write import marker: existing config at {} is \
                 not valid TOML ({}). Fix the file (or move it aside) and \
                 retry.",
                config_path.display(),
                e
            )
        })?,
        Err(e) if e.kind() == std::io::ErrorKind::NotFound => TomlValue::Table(TomlMap::new()),
        Err(e) => return Err(e.into()),
    };
    let table = root
        .as_table_mut()
        .ok_or_else(|| anyhow::anyhow!("config root is not a table"))?;
    let compat = table
        .entry("claude_compat")
        .or_insert_with(|| TomlValue::Table(TomlMap::new()));
    let compat_table = compat
        .as_table_mut()

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Open the config file at the path in the message and fix the TOML syntax reported by the parse error (often a trailing comma).
  2. Temporarily move the file aside so write_import_marker creates a fresh table, then re-apply your settings.
  3. Validate the file with a TOML linter/parser (e.g. taplo, tomlq) before retrying.

Example fix

// before (config.toml)
[ui]
theme = "dark",

// after
[ui]
theme = "dark"
Defensive patterns

Strategy: validation

Validate before calling

if path.exists() {
    let s = std::fs::read_to_string(&path)?;
    toml::from_str::<toml::Value>(&s)
        .map_err(|e| anyhow::anyhow!("config {} invalid TOML: {}", path.display(), e))?;
}

Type guard

fn is_valid_toml_table(s: &str) -> bool {
    toml::from_str::<toml::Value>(s)
        .map(|v| v.is_table())
        .unwrap_or(false)
}

Try / catch

match write_import_marker(&path) {
    Err(e) if e.to_string().contains("not valid TOML") => {
        eprintln!("Fix config TOML first: {e}");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling mark_claude_imported (or write_import_marker) when the target config file exists but contains invalid TOML, e.g. a trailing comma or malformed table header.

Common situations: A user hand-edited their config file and left a trailing comma; another tool corrupted the file; a merge left partial TOML syntax behind.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/af9c781b8f16fa40. Report an issue: GitHub.