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

  1. Read the message: it names the source (`from`) and destination (`into`) definitions and the expected/found types.
  2. Make both sources use the same type for that key (e.g. both string, or both array).
  3. Check `$CARGO_HOME/config.toml`, project `.cargo/config.toml`, and relevant `CARGO_*` env vars for the offending key.
  4. 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

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


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/6353477f8f911ea3.json. Report an issue: GitHub.