rust-lang/cargo · error

argument for --color must be auto, always, or never, but fou

Error message

argument for --color must be auto, always, or never, but found `{}`

What it means

From ColorChoice::from_str (crates/cargo-util-terminal/src/shell.rs:584-600), the FromStr impl that parses Cargo's global --color option. Only the case-sensitive lowercase strings `always`, `never`, and `auto` map to a variant; everything else bails with this anyhow error, which clap surfaces as an invalid-value error. The three variants map to anstream::ColorChoice (Always / Never / CargoAuto).

Source

Thrown at crates/cargo-util-terminal/src/shell.rs:593

    fn to_anstream_color_choice(self) -> anstream::ColorChoice {
        match self {
            ColorChoice::Always => anstream::ColorChoice::Always,
            ColorChoice::Never => anstream::ColorChoice::Never,
            ColorChoice::CargoAuto => anstream::ColorChoice::Auto,
        }
    }
}

impl std::str::FromStr for ColorChoice {
    type Err = anyhow::Error;
    fn from_str(color: &str) -> Result<Self, Self::Err> {
        let cfg = match color {
            "always" => ColorChoice::Always,
            "never" => ColorChoice::Never,

            "auto" => ColorChoice::CargoAuto,

            arg => anyhow::bail!(
                "argument for --color must be auto, always, or \
                     never, but found `{}`",
                arg
            ),
        };
        Ok(cfg)
    }
}

fn supports_color(choice: anstream::ColorChoice) -> bool {
    match choice {
        anstream::ColorChoice::Always
        | anstream::ColorChoice::AlwaysAnsi
        | anstream::ColorChoice::Auto => true,
        anstream::ColorChoice::Never => false,
    }
}

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Use exactly one of: `auto`, `always`, or `never` (lowercase).
  2. Omit the flag entirely; Cargo defaults to auto.
  3. If driving Cargo from a wrapper, map your boolean to one of the three accepted strings before passing it.

Example fix

// before
cargo build --color=on

// after
cargo build --color=always
Defensive patterns

Strategy: validation

Validate before calling

// Validate a --color value before it reaches ColorChoice::from_str
fn valid_color_choice(s: &str) -> bool {
    matches!(s, "always" | "never" | "auto")
}

let color = if valid_color_choice(raw) { raw } else { "auto" };

Type guard

fn is_valid_color_choice(s: &str) -> bool {
    matches!(s, "always" | "never" | "auto")
}

Try / catch

// Parse defensively if you must take arbitrary input
use cargo_util_terminal::ColorChoice;
use std::str::FromStr;
let choice = match ColorChoice::from_str(raw) {
    Ok(c) => c,
    Err(_) => ColorChoice::CargoAuto, // fall back to auto
};

Prevention

When it happens

Trigger: Running any cargo command with `--color yes`, `--color=on`, `--color TRUE`, `--color 1`, or a misspelled value. Also triggered programmatically by calling ColorChoice::from_str("on") from code embedding cargo-util-terminal.

Common situations: Scripts, makefiles, or CI configs that set --color=on (valid in many GNU tools but not Cargo). Muscle memory from `grep --color=always`. A typo like `--colour=auto`. Aliases piping Cargo output through tools that expect yes/no.

Related errors


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