You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
motief/docs/solutions/build-errors/uv-lock-pytest-missing-sour...

72 lines
2.9 KiB

---
title: "uv.lock parse error due to pytest entry missing source"
module: tooling
component: tooling
problem_type: build_error
severity: medium
date: 2026-04-05
tags: [uv, lockfile, pytest, packaging, streamlit]
---
Problem
-------
Running `uv` commands failed with a parse error in `uv.lock` caused by an ambiguous/malformed `pytest` entry that lacked a proper `source` field and conflicted with another package entry.
Symptoms
--------
- `uv run streamlit run Home.py` failed with: "Dependency `pytest` has missing `source` field but has more than one matching package".
- `uv lock` and `uv add` also failed because `uv.lock` could not be parsed.
What didn't work
----------------
- Attempting `uv add "pytest>=9.0.2" --dev` failed because the lockfile parser errored before the command could modify anything.
- Manual edits to `uv.lock` were used as a temporary stop-gap (allowed `uv` to run) but are not a durable solution because `uv.lock` is generated.
Solution
--------
1. Regenerate the lockfile from `pyproject.toml` so `uv.lock` and project metadata are consistent:
- Run: `uv lock`
- Inspect the resulting `uv.lock` to ensure `pytest` appears as a single `[[package]]` entry with a `source` field and expected hashes.
2. Commit the regenerated lock locally (do not push without review):
- `git add uv.lock`
- `git commit -m "chore: regenerate uv.lock (resolve pytest source ambiguity)"`
Why this works
--------------
- `uv.lock` is the canonical, generated lockfile. The parser expects each package entry to have an unambiguous `source` so `uv` can resolve hashes and reproducible installs. Regenerating produces a consistent lockfile derived from `pyproject.toml` and resolves duplicated/malformed entries.
- Manual edits fix symptoms but can be overwritten or lead to inconsistent state; regenerating ensures upstream metadata and lockfile match the resolver's expectations.
Prevention
----------
- Avoid hand-editing `uv.lock`. When a lockfile parse error appears, prefer regenerating with `uv lock`.
- Add a lightweight CI check to ensure `uv lock --check` (or `uv lock` with no changes) passes before merging changes that touch dependencies or the lockfile.
- Make `pytest` (and other dev tools) authoritative in `pyproject.toml` under `dependency-groups.dev` so the resolver has a single source of truth.
Verification
------------
- After regeneration, verify `uv` commands work and tests run:
- `uv run streamlit run Home.py` → Streamlit should start and print Local/Network URL
- `.venv/bin/python -m pytest tests/ -q` → Confirm tests run (example in this run: `171 passed, 2 skipped`).
Related files
-------------
- `uv.lock`
- `pyproject.toml`
If you want, I can:
1) Run the Streamlit verification now, or
2) Propose a small CI job snippet to enforce `uv lock --check`, or
3) Create a short PR description if you want this committed change pushed and opened as a PR.