rust-lang/cargo · error

env var was not array

Error message

env var was not array

What it means

This panic fires inside merge_env_in_list() when parsing an environment variable as a TOML array under the -Z advanced-env unstable feature. The code checks env_val.starts_with('[') && env_val.ends_with(']') and then parses it with toml::Value::parse. It expects the result to be an array, but a TOML value like [table] or [{...}] could parse successfully as a non-array (inline table) despite the bracket check.

Source

Thrown at src/context/mod.rs:1114

            // Keep existing config if higher priority than env (e.g., --config CLI),
            // otherwise clear for env
            if output
                .first()
                .map(|o| o.definition() > &env_def)
                .unwrap_or_default()
            {
                return Ok(());
            } else {
                output.clear();
            }
        }

        if self.cli_unstable().advanced_env && env_val.starts_with('[') && env_val.ends_with(']') {
            // Parse an environment string as a TOML array.
            let toml_v = env_val.parse::<toml::Value>().map_err(|e| {
                ConfigError::new(format!("could not parse TOML list: {}", e), env_def.clone())
            })?;
            let values = toml_v.as_array().expect("env var was not array");
            for value in values {
                // Until we figure out how to deal with it through `-Zadvanced-env`,
                // complex array types are unsupported.
                let s = value.as_str().ok_or_else(|| {
                    ConfigError::new(
                        format!("expected string, found {}", value.type_str()),
                        env_def.clone(),
                    )
                })?;
                output.push(CV::String(s.to_string(), env_def.clone()))
            }
        } else {
            output.extend(
                env_val
                    .split_whitespace()
                    .map(|s| CV::String(s.to_string(), env_def.clone())),
            );
        }

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Ensure the environment variable value is a valid TOML array of strings, e.g. CARGO_REGISTRY_CREDENTIAL_PROVIDER="['cargo:token-from-stdin']".
  2. Disable -Zadvanced-env if not needed and use --config or config files instead.
  3. Validate the env var with a TOML parser externally before invoking cargo.

Example fix

// before
let values = toml_v.as_array().expect("env var was not array");
// after
let toml_v = env_val.parse::<toml::Value>().map_err(|e| {
    ConfigError::new(format!("could not parse TOML list: {}", e), env_def.clone())
})?;
let values = toml_v.as_array().ok_or_else(|| {
    ConfigError::new(format!("expected array, found {}", toml_v.type_str()), env_def.clone())
})?;
Defensive patterns

Strategy: validation

Validate before calling

// Validate env var is a TOML array before passing to cargo
fn validate_env_array(var_name: &str) -> Result<(), String> {
    if let Ok(val) = std::env::var(var_name) {
        if val.starts_with('[') && val.ends_with(']') {
            let parsed: toml::Value = val.parse().map_err(|e| format!("{}: {}", var_name, e))?;
            if !parsed.is_array() {
                return Err(format!("{}: expected TOML array, got {}", var_name, parsed.type_str()));
            }
        }
    }
    Ok(())
}

Type guard

fn is_valid_toml_array(val: &str) -> bool {
    if !(val.starts_with('[') && val.ends_with(']')) { return false; }
    val.parse::<toml::Value>().ok().map_or(false, |v| v.is_array())
}

Prevention

When it happens

Trigger: Setting a CARGO_ environment variable (with -Zadvanced-env enabled) to a value that starts with [ and ends with ] but parses as a TOML inline table rather than an array — e.g., CARGO_SOMELIST = "{ key = 'val' }" would fail the bracket check, but edge cases in TOML parsing could produce a non-array Value.

Common situations: Using -Zadvanced-env to pass list-valued config via environment variables and accidentally providing a value that TOML interprets as a table or other non-array type; cargo version mismatch where the TOML parser accepts constructs the expect was not designed for.

Related errors


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