astral-sh/ruff · error · clap::Error

InvalidUtf8

InvalidUtf8

Error message

invalid UTF-8 was detected in one or more arguments

What it means

The `--config` value parser accepts either a path to an existing config file (which may legitimately be non-UTF-8 at the OS level) or an inline UTF-8 TOML string. If the raw argument is not valid UTF-8 AND the bytes do not name an existing file, clap fails with ErrorKind::InvalidUtf8 and this default message.

Source

Thrown at crates/ruff/src/args.rs:1003

}

impl TypedValueParser for ConfigArgumentParser {
    type Value = SingleConfigArgument;

    fn parse_ref(
        &self,
        cmd: &clap::Command,
        arg: Option<&clap::Arg>,
        value: &std::ffi::OsStr,
    ) -> Result<Self::Value, clap::Error> {
        // Convert to UTF-8.
        let Some(value) = value.to_str() else {
            // But respect non-UTF-8 paths.
            let path_to_config_file = PathBuf::from(value);
            if path_to_config_file.is_file() {
                return Ok(SingleConfigArgument::FilePath(path_to_config_file));
            }
            return Err(clap::Error::new(clap::error::ErrorKind::InvalidUtf8));
        };

        // Expand environment variables and tildes.
        if let Ok(path_to_config_file) =
            shellexpand::full(value).map(|config| PathBuf::from(&*config))
        {
            if path_to_config_file.is_file() {
                return Ok(SingleConfigArgument::FilePath(path_to_config_file));
            }
        }

        let _guard = ValueSourceGuard::new(ValueSource::Cli, false);

        let config_parse_error = match toml::Table::from_str(value) {
            Ok(table) => match Options::from_toml_table(table) {
                Ok(option) => {
                    if option.extend.is_none() {
                        return Ok(SingleConfigArgument::SettingsOverride(Arc::new(option)));

View on GitHub (pinned to d1087a4b9e)

Solutions

  1. Verify the exact bytes being passed (`printf '%s' "$cfg" | xxd`) and that a file exists at that path.
  2. Re-enter the path in a UTF-8 locale (`export LANG=C.UTF-8`) so the shell produces UTF-8 bytes.
  3. Rename the config file to a valid-UTF-8 name and reference that.
  4. Alternatively pass settings inline as UTF-8 TOML, e.g. `--config 'line-length = 100'`.
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
cfg="$1"
if ! printf '%s' "$cfg" | iconv -f UTF-8 -t UTF-8 >/dev/null 2>&1 && [ ! -e "$cfg" ]; then
  echo "--config value is not UTF-8 and no file exists at that path" >&2
  exit 1
fi
exec ruff check --config "$cfg" .

Prevention

When it happens

Trigger: `ruff check --config <non-UTF-8 bytes>` where no file exists at those bytes — a mis-encoded path typed in a legacy-locale terminal, or a config file that was renamed or deleted.

Common situations: Terminal/locale mismatches producing Latin-1 filenames; scripts piping raw bytes into argv; referring to a moved config file by its old name.

Understand the failure class

Related errors


AI-assisted analysis of astral-sh/ruff@d1087a4b9e (2026-08-20). Data as JSON: /api/errors/59d95245fbb5947d. Report an issue: GitHub.