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
- Open the config file at the path in the message and fix the TOML syntax reported by the parse error (often a trailing comma).
- Temporarily move the file aside so write_import_marker creates a fresh table, then re-apply your settings.
- 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
- Never hand-edit config TOML without validating afterwards (taplo, tomlq).
- Run the import on a committed/VCS-tracked config so bad edits are revertible.
- Keep one canonical serializer for the config instead of manual edits.
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
- Failed to parse config.toml: {e}
- refusing to import: existing config at {} is not valid TOML
- refusing to overwrite unparseable {}: {}; fix the syntax bef
- refusing to rewrite unparseable {}: {e}
- refusing to overwrite unparseable {}: {}; save a backup and
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/af9c781b8f16fa40.
Report an issue: GitHub.