--- 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.