nikivdev/code · error
expected [{}] to be a table in global flow config
Error message
expected [{}] to be a table in global flow config What it means
When Flow edits the global TOML config, it ensures a given key holds a table, inserting a new table only if the key is absent. If the key exists but its value is NOT a table (e.g. a string, integer, or array), the function refuses to overwrite the existing value and bails; the same message is returned if the value cannot be borrowed as a mutable table.
Source
Thrown at src/ai.rs:9481
return Ok(toml::value::Table::new());
}
let value: TomlValue =
toml::from_str(&content).with_context(|| format!("failed to parse {}", path.display()))?;
value
.as_table()
.cloned()
.ok_or_else(|| anyhow::anyhow!("global flow config must be a TOML table"))
}
fn ensure_toml_table<'a>(
root: &'a mut toml::value::Table,
key: &str,
) -> Result<&'a mut toml::value::Table> {
let needs_insert = !matches!(root.get(key), Some(TomlValue::Table(_)));
if needs_insert {
if root.contains_key(key) {
bail!("expected [{}] to be a table in global flow config", key);
}
root.insert(key.to_string(), TomlValue::Table(toml::value::Table::new()));
}
root.get_mut(key)
.and_then(TomlValue::as_table_mut)
.ok_or_else(|| anyhow::anyhow!("expected [{}] to be a table in global flow config", key))
}
fn write_string_atomically(path: &Path, content: &str) -> Result<()> {
let parent = path
.parent()
.ok_or_else(|| anyhow::anyhow!("missing parent for {}", path.display()))?;
fs::create_dir_all(parent)?;
let temp = parent.join(format!(
".{}.tmp-{}-{}",
path.file_name()
.and_then(|value| value.to_str())
.unwrap_or("flow.toml"),View on GitHub (pinned to a747e741ae)
Solutions
- Open the global flow config file and change the offending key from a scalar/array to a table: `key = "x"` → `[key]\nfield = "x"`
- Or delete the conflicting key and re-run the command so it inserts a fresh empty table
- Back up the config first, then validate the TOML (e.g. with a TOML linter) before re-running
Example fix
// before (global flow config, invalid) daemon = 3 // after [daemon] enabled = true
Defensive patterns
Strategy: validation
Validate before calling
// Shell/Rust: inspect the global config TOML before running commands that write sections
# fail if the target key is not a table
python3 -c "import tomllib,sys; c=tomllib.load(open('global-flow-config.toml','rb')); k='daemon'; assert not (k in c and not isinstance(c[k], dict)), f'{k} is not a table'" Type guard
fn is_toml_table(v: &toml::Value) -> bool {
matches!(v, toml::Value::Table(_))
} Try / catch
match enable_global_flow_config(root, "daemon") {
Ok(table) => { /* edit table */ }
Err(e) if e.to_string().contains("to be a table in global flow config") => {
let key = /* extract from message */;
eprintln!("Fix [{}]: replace the scalar/array value with a [{}] section in the global config", key, key);
}
Err(e) => return Err(e),
} Prevention
- Validate the global flow config with a TOML linter after hand edits
- Never define keys as scalars/arrays that later commands write as [section] tables
- Back up the global config before running commands that mutate it
- When migrating config formats, run the project's migration/doctor tooling instead of hand-editing
When it happens
Trigger: Running a command that writes a `[section]` into the global flow config (e.g. enabling Codex global settings) while the global config file already defines that key as a scalar or array — e.g. `daemon = 3` instead of `[daemon]`.
Common situations: Hand-edited ~/.config/flow config where a section was written as a plain key/value; an older config format or migration left a scalar where the new code expects a table; automated scripts appending settings that collide with table keys.
Related errors
- deploy_task '{}' not found. Available tasks: {}
- No bootstrap secrets configured. Add cloudflare.bootstrap_se
- No [cloudflare] or [storage] env keys configured in flow.tom
- No proxy targets configured. Add [[proxies]] to flow.toml
- repos root is immutable; use {} or {} or set {}=1 to overrid
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/ec84203b77529e0a.
Report an issue: GitHub.