rust-lang/cargo · error

`{}` expected {}, but found a {}

Error message

`{}` expected {}, but found a {}

What it means

During config deserialization, when a value's type does not match what the schema expects for a key, ConfigError::expected (error.rs:23-33) builds '`<key>` expected <expected>, but found a <found.desc()>'. The definition of the offending value is attached. This is the underlying type-error behind many 'invalid configuration for key' messages.

Source

Thrown at src/context/error.rs:25

/// Internal error for serde errors.
#[derive(Debug)]
pub struct ConfigError {
    error: anyhow::Error,
    definition: Option<Definition>,
}

impl ConfigError {
    pub(super) fn new(message: String, definition: Definition) -> ConfigError {
        ConfigError {
            error: anyhow::Error::msg(message),
            definition: Some(definition),
        }
    }

    pub(super) fn expected(key: &ConfigKey, expected: &str, found: &ConfigValue) -> ConfigError {
        ConfigError {
            error: anyhow::anyhow!(
                "`{}` expected {}, but found a {}",
                key,
                expected,
                found.desc()
            ),
            definition: Some(found.definition().clone()),
        }
    }

    pub(super) fn is_missing_field(&self) -> bool {
        self.error.downcast_ref::<MissingFieldError>().is_some()
    }

    pub(super) fn missing(key: &ConfigKey) -> ConfigError {
        ConfigError {
            error: anyhow::anyhow!("missing config key `{}`", key),
            definition: None,
        }

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Read the message for the key name and the expected vs found types.
  2. Consult the config reference for that key's expected type and fix the value accordingly.
  3. Locate the source via the attached definition (which file/env set it).

Example fix

# before
[profile.release]
opt-level = "fast"   # string, but integer expected
# after
[profile.release]
opt-level = 3
Defensive patterns

Strategy: validation

Validate before calling

# Lint config.toml value types against the schema before building.
# Example: jobs must be an integer
python3 -c "import tomllib; d=tomllib.load(open('.cargo/config.toml','rb'));\
  assert isinstance(d.get('build',{}).get('jobs',0), int)"

Prevention

When it happens

Trigger: A config key that the schema declares as one type receives another, e.g. `[net] retry = "yes"` where retry is a bool, or `profiles.dev opt-level = "fast"`. Produced by ConfigValue accessors (i64/string/table/bool) and the typed `get` deserializer.

Common situations: Typos in config.toml units; passing a string where an integer/bool/list is expected; mismatched value shapes between env var and config file.

Related errors


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