astral-sh/ruff · error · std::io::Error

NotFound

NotFound

Error message

failed to resolve uv executable: {error}

What it means

When ty detects a uv workspace, it runs `uv workspace metadata --frozen --active` to learn the workspace root and environment. The uv binary is located via the `UV` env var, falling back to a PATH search (`system.which("uv")`); any WhichError (not found, unreadable PATH entries, unresolvable executable) is converted to an io::Error of kind NotFound with this message, surfacing as UvWorkspaceError::Invocation during environment discovery.

Solutions

  1. Install uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`, brew, or pip) and restart the editor/terminal so PATH refreshes.
  2. Set `UV` to the absolute path of the uv executable for the process running ty.
  3. Launch GUI editors from a shell (`code .`) or fix the GUI environment's PATH (e.g. `launchctl setenv PATH ...` on macOS).
  4. If the project should not be treated as a uv workspace, check for a stray [tool.uv] workspace marker or point ty at the intended Python environment in its settings.

Example fix

# before: editor spawned without uv on PATH
$ open -a 'Visual Studio Code' .   # ty logs: failed to resolve uv executable

# after: pin the resolver via UV and launch from a shell
$ export UV="$(command -v uv)" && code .
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
if ! command -v uv >/dev/null 2>&1; then
  echo "uv not found on PATH; ty needs it for uv workspaces" >&2
  exit 1
fi
export UV="$(command -v uv)"   # pin it for children like the editor/ty

Prevention

When it happens

Trigger: ty (CLI or LSP inside an editor) opens a uv-managed project while `uv` is not on the process's PATH and `UV` is unset, or `UV` points to a path that cannot be resolved or executed.

Common situations: macOS GUI editors that do not inherit the shell PATH where uv was installed; CI images without uv; uv installed in a cargo/bin directory while the editor is launched from the Dock; `UV` pointing at a moved binary.

Understand the failure class

Background: "Not Found" / HTTP 404 Errors: What They Mean and How to Fix Them Across Libraries — this error's family across 6 libraries.

Related errors


AI-assisted analysis of astral-sh/ruff@5bb508f594 (2026-08-20). Data as JSON: /api/errors/1c4dd2dc3de835fb. Report an issue: GitHub.

Appendix: source

Thrown at crates/ty_project/src/uv/metadata.rs:86

            resolution: metadata.resolution,
            module_owners: metadata.module_owners,
        })
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, get_size2::GetSize)]
pub(crate) struct WorkspaceMember {
    pub(crate) name: Box<str>,
    /// Directory containing the member's `pyproject.toml`.
    pub(crate) path: SystemPathBuf,
    #[serde(deserialize_with = "string_interner::deserialize")]
    id: CharStr,
}

#[derive(Debug, Error)]
pub(crate) enum UvMetadataError {
    #[error("Failed to invoke `uv workspace metadata`: {0}")]
    Invocation(#[source] std::io::Error),

    #[error("`uv workspace metadata` failed with status {status}: {stderr}")]
    CommandFailed {
        status: std::process::ExitStatus,
        stderr: String,
    },

    #[error("invalid `uv workspace metadata` JSON: {0}")]
    InvalidMetadata(serde_json::Error),

    #[error("non-Unicode {description} returned by `uv workspace metadata`: `{path}`", path = path.display())]
    NonUnicodePath {
        description: &'static str,
        path: PathBuf,
    },

    #[error("missing {description} returned by `uv workspace metadata`: `{path}`")]
    MissingDirectory {

View on GitHub (pinned to 5bb508f594)