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