rust-lang/rust · error · anyhow::Error

environment variable {var} is not utf-8

Error message

environment variable {var} is not utf-8

What it means

Bailed by env_string when std::env::var returns VarError::NotUnicode — the environment variable exists but its OS string content cannot be converted to valid UTF-8. The tool refuses to guess at a lossy conversion and aborts.

Source

Thrown at src/tools/generate-copyright/src/main.rs:215

                })
            }
        }
    }
}

/// A License has an SPDX license name and a list of copyright holders.
#[derive(serde::Deserialize, Clone, Debug, PartialEq, Eq)]
struct License {
    spdx: String,
    copyright: Vec<String>,
}

/// Grab an environment variable as string, or fail nicely.
fn env_string(var: &str) -> Result<String, Error> {
    match std::env::var(var) {
        Ok(var) => Ok(var),
        Err(std::env::VarError::NotUnicode(_)) => {
            anyhow::bail!("environment variable {var} is not utf-8")
        }
        Err(std::env::VarError::NotPresent) => anyhow::bail!("missing environment variable {var}"),
    }
}

/// Grab an environment variable as a PathBuf, or fail nicely.
fn env_path(var: &str) -> Result<PathBuf, Error> {
    if let Some(var) = std::env::var_os(var) {
        Ok(var.into())
    } else {
        anyhow::bail!("missing environment variable {var}")
    }
}

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Re-set the variable with a valid UTF-8 value: export VAR='<utf8 value>'.
  2. On Windows, ensure the system/code-page locale is UTF-8 (chcp 65001) or use PowerShell with $env:VAR set to a Unicode string.
  3. Find which process set the non-UTF-8 value and fix the source.

Example fix

// before: only accept strict UTF-8
Err(std::env::VarError::NotUnicode(_)) =>
    anyhow::bail!("environment variable {var} is not utf-8"),

// after: fall back to OsString->PathBuf for path-like vars
Err(std::env::VarError::NotUnicode(os)) => {
    tracing::warn!("environment variable {var} is not utf-8; using raw OS string");
    Ok(os.to_string_lossy().into_owned())
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate env vars are UTF-8 before the tool runs, with a clear message:
fn ensure_utf8_env(vars: &[&str]) -> Result<(), String> {
    for v in vars {
        if let Some(val) = std::env::var_os(v) {
            if val.to_str().is_none() {
                return Err(format!("env var {v} is not valid UTF-8"));
            }
        }
    }
    Ok(())
}

Type guard

null

Try / catch

// Wrap env_string callers when extending the tool:
match env_string(var) {
    Ok(s) => s,
    Err(e) if e.to_string().contains("not utf-8") => {
        // last-resort: use the raw OS string lossily, or surface to user
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling generate-copyright with an environment variable (e.g. a path or license config var) set to a value containing non-UTF-8 bytes. Common on Windows with legacy code pages, or when a var is populated from a binary blob.

Common situations: A PATH or config var containing locale-specific bytes on Windows; exporting a var from a script that wrote raw bytes; a var accidentally set to binary file contents.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/0f58aca9a10e499a. Report an issue: GitHub.