rust-lang/cargo · error
failed to merge config value from `{}` into `{}`: expected {
Error message
failed to merge config value from `{}` into `{}`: expected {}, but found {} What it means
When Cargo merges layered config (CLI > env > project > home) it calls ConfigValue::merge (config_value.rs:184-212). Scalars can override each other, but merging across a structural boundary is forbidden: you cannot merge a List/Table with a scalar or with a different structure. On such a type clash it returns 'failed to merge config value from `<source def>` into `<dest def>`: expected <X>, but found <Y>'. The definition locations point at the two conflicting config sources.
Source
Thrown at src/context/config_value.rs:205
{} and {}",
key,
entry.definition(),
new_def,
)
})?;
}
Entry::Vacant(entry) => {
entry.insert(value);
}
};
}
}
// Allow switching types except for tables or arrays.
(expected @ &mut CV::List(_, _), found)
| (expected @ &mut CV::Table(_, _), found)
| (expected, found @ CV::List(_, _))
| (expected, found @ CV::Table(_, _)) => {
return Err(anyhow!(
"failed to merge config value from `{}` into `{}`: expected {}, but found {}",
found.definition(),
expected.definition(),
expected.desc(),
found.desc()
));
}
(old, mut new) => {
if force || is_higher_priority {
mem::swap(old, &mut new);
}
}
}
Ok(())
}
pub fn i64(&self, key: &str) -> CargoResult<(i64, &Definition)> {View on GitHub (pinned to 0e07a15537)
Solutions
- Read the message: it names the source (`from`) and destination (`into`) definitions and the expected/found types.
- Make both sources use the same type for that key (e.g. both string, or both array).
- Check `$CARGO_HOME/config.toml`, project `.cargo/config.toml`, and relevant `CARGO_*` env vars for the offending key.
- If you need to override, remove the lower-priority value rather than change its type.
Example fix
# before (config.toml) [build] rustflags = ["-A", "warnings"] # env export CARGO_BUILD_RUSTFLAGS="-D warnings" # scalar vs array -> clash # after export CARGO_BUILD_RUSTFLAGS="-A warnings" # both array-encoded, or unset one
Defensive patterns
Strategy: validation
Validate before calling
# Validate config layering doesn't change a key's type. # Use `cargo config get` (or inspect) to see the merged value and its source: cargo config get build.rustflags # confirms resolved type & origin
Prevention
- Keep a single canonical source for each config key; avoid setting the same key in home + project + env.
- Use arrays consistently for list-type keys across all sources.
- Run `cargo config get` to inspect merged config before debugging mysterious type errors.
When it happens
Trigger: Two config sources set the same key to incompatible types, e.g. `[build] jobs = 4` (integer) in config.toml but `CARGO_BUILD_JOCS=a,b` style list in env, or a table where a string is expected. Any merge where one side is CV::List/CV::Table and the other is not.
Common situations: Setting a config key as a string in config.toml but as an array in a higher-priority source; env var that should be a list vs. config that is a scalar; conflicting config.toml between home and project.
Related errors
- `{}` expected {}, but found a {}
- invalid configuration for key `{}` {}
- subcommand is required, add a subcommand to the command alia
- alias {} has unresolvable recursive definition: {} -> {}
- subcommand is required, but `{alias_name}` is empty
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/6353477f8f911ea3.json.
Report an issue: GitHub.