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

Temporary directory path is not valid UTF-8: {}

Error message

Temporary directory path is not valid UTF-8: {}

What it means

After creating its scratch directory via `tempfile::Builder`, the harness converts the temp path to a `SystemPath`; `SystemPath::from_std_path` returns None when the path is not valid UTF-8 (it does not lossily convert), so the run aborts. In practice this means TMPDIR — or the OS default temp location — points into a non-Unicode path.

Source

Thrown at crates/ty_completion_eval/src/main.rs:159

    let truth = cwd.join("crates").join("ty_completion_eval").join("truth");
    anyhow::ensure!(
        truth.as_std_path().exists(),
        "{truth} does not exist: ty's completion evaluation must be run from the root \
         of the ruff repository",
        truth = truth.as_std_path().display(),
    );

    // The temporary directory at which we copy our truth
    // data to. We do this because we can't use the truth
    // data as-is with its `<CURSOR>` annotations (and perhaps
    // any other future annotations we add).
    let mut tmp_eval_dir = tempfile::Builder::new()
        .prefix("ty-completion-eval-")
        .tempdir()
        .context("Failed to create temporary directory")?;
    let tmp_eval_path = SystemPath::from_std_path(tmp_eval_dir.path())
        .ok_or_else(|| {
            anyhow::anyhow!(
                "Temporary directory path is not valid UTF-8: {}",
                tmp_eval_dir.path().display()
            )
        })?
        .to_path_buf();

    let sources = TaskSource::all(&truth)?;
    match args.command {
        Command::ShowOne(ref cmd) => {
            tmp_eval_dir.disable_cleanup(cmd.keep_tmp_dir);

            let Some(source) = sources
                .iter()
                .find(|source| cmd.matches_source_task(source))
            else {
                anyhow::bail!("could not find task named `{}`", cmd.task_name);
            };
            let tasks = source.to_tasks(&tmp_eval_path)?;

View on GitHub (pinned to 672bb4edf0)

Solutions

  1. Point TMPDIR at a clean location: `export TMPDIR=/tmp` and re-run
  2. Fix the container image or wrapper script that sets TMPDIR to a non-UTF-8 path
  3. Verify with a UTF-8 round-trip check before invoking the harness

Example fix

# before
TMPDIR=$'/tmp/bad\xff' cargo run -p ty_completion_eval -- all
# after
export TMPDIR=/tmp && cargo run -p ty_completion_eval -- all
Defensive patterns

Strategy: validation

Validate before calling

python3 -c 'import os,sys; os.environ.get("TMPDIR", "/tmp").encode("utf-8")' 2>/dev/null \
  || { echo "TMPDIR is not valid UTF-8" >&2; exit 2; }

Prevention

When it happens

Trigger: `TMPDIR` exported to a path containing invalid UTF-8 bytes; containers/sandboxes whose temp mount or env carries byte-mangled paths; the message echoes the offending path via `display()`.

Common situations: CI containers with odd TMPDIR values; wrappers that derive TMPDIR from a non-UTF-8 workspace path; test harnesses chaining temp dirs from other tools.

Related errors


AI-assisted analysis of astral-sh/ruff@672bb4edf0 (2026-08-16). Data as JSON: /api/errors/80980de906265a74. Report an issue: GitHub.