astral-sh/ruff · error

Expected uv to create a lockfile at '{}'

Error message

Expected uv to create a lockfile at '{}'

What it means

In ty's test harness, `setup_venv` creates a virtual environment and runs `uv` to generate a `uv.lock` lockfile in a temp directory, then copies it to the expected location. This error is thrown when `uv` completed without leaving a lockfile at the expected temp path, meaning the external dependency provisioning failed silently.

Source

Thrown at crates/ty_test/src/external_dependencies.rs:138

            );
        }

        bail!(
            "`uv sync` failed with exit code {:?}:\n{}",
            uv_sync_output.status.code(),
            stderr
        );
    }

    // In upgrade mode, copy the generated lockfile back to the source location
    if upgrade_lockfile {
        let temp_lockfile = temp_path.join("uv.lock");
        let temp_lockfile = temp_lockfile.as_std_path();
        if temp_lockfile.exists() {
            std::fs::copy(temp_lockfile, lockfile_path)
                .with_context(|| format!("Failed to write lockfile to '{lockfile_path}'"))?;
        } else {
            bail!(
                "Expected uv to create a lockfile at '{}'",
                temp_lockfile.display()
            );
        }
    }

    let venv_path = temp_path.join(".venv");

    copy_site_packages_to_db(db, &venv_path, dest_venv_path, python_version)
}

/// Copy the site-packages directory from a real virtual environment to the in-memory filesystem of `db`.
///
/// This recursively copies all files from the venv's site-packages directory into the
/// in-memory filesystem at the specified destination path.
fn copy_site_packages_to_db(
    db: &mut Db,
    venv_path: &SystemPath,

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Run the same `uv` command manually in a scratch directory and confirm it produces `uv.lock`; fix any uv config (e.g. `[tool.uv] package = false` or `--no-lock`-style options) that suppresses lockfile creation.
  2. Check which `uv` binary is on PATH (`which uv`, `uv --version`) and align it with the version the test harness expects.
  3. Verify write permissions and free space in the temp directory so uv can create the lockfile.
  4. Re-run the test with `UV_VERBOSE`-style debugging or inspect the captured uv stderr to find why the lock step failed.

Example fix

// before
// setup runs: uv sync (no lock produced because lockfile generation is disabled)
// after
// setup runs: uv sync --locked  (or remove `[tool.uv]` settings that skip lockfile generation so uv.lock is created)
Defensive patterns

Strategy: validation

Validate before calling

let temp_lockfile = temp_path.join("uv.lock");
if !temp_lockfile.exists() {
    eprintln!("uv did not produce {}; aborting setup", temp_lockfile.display());
    std::process::exit(1);
}

Type guard

fn has_lockfile(dir: &std::path::Path) -> bool { dir.join("uv.lock").is_file() }

Try / catch

// Rust: use the anyhow context on the run and check lockfile existence right after the uv command
let output = run_uv(&venv_dir).context("uv provisioning failed")?;
anyhow::ensure!(temp_path.join("uv.lock").exists(), "uv produced no lockfile");

Prevention

When it happens

Trigger: Calling the mdtest/external-dependencies test setup when the `uv lock`/install command exits successfully but no `uv.lock` exists at `temp_path.join("uv.lock")`.

Common situations: A broken or overridden `uv` on PATH, a project configuration that disables lockfile creation, a `uv` version that writes the lockfile elsewhere, or filesystem/permission issues in the temp directory.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/4c3d881ffce13302. Report an issue: GitHub.