fix(deps): repair uv.lock parse failure from pyjwt 2.13.0 bump (11 servers) - #4536
Conversation
…rvers) Dependabot PR #4503 (merged as a7b3263) bumped pyjwt 2.10.1 -> 2.13.0 across 30 directories. pyjwt 2.13.0 introduced a new conditional dependency on typing-extensions for `python_full_version < '3.11'`. Dependabot edited each uv.lock surgically rather than re-resolving, and in 11 of the 30 locks it wrote that new edge with an explicit version pin: { name = "typing-extensions", version = "4.14.0", source = { ... }, marker = ... } In uv.lock, a dependency edge carries `version`/`source` only when the lock holds multiple forked versions of that package. These 11 locks each contain a single typing-extensions entry (4.16.0), so the pinned edge (4.13.2 or 4.14.0) referenced a package that does not exist in the lock, and uv rejected the file at parse time: error: Failed to parse `uv.lock` Caused by: For package `pyjwt==2.13.0 @ registry+https://pypi.org/simple`, found dependency `typing-extensions==4.14.0` with no locked package This broke the `Install dependencies` step (`uv sync --frozen --all-extras --dev`) for all 11 servers. The other 19 locks received a bare edge and were unaffected. Fix: drop the bogus version/source pin so each edge binds to the single locked typing-extensions, which is the canonical form uv itself emits (and exactly what the 19 healthy locks contain). `uv lock` cannot regenerate these files because it fails on the same parse error before it can re-resolve. No resolved versions change - typing-extensions 4.16.0 was already the only locked version. This restores the lock to a parseable state. Verified for all 11 servers on Python 3.10 (the version where the marker is active): `uv sync --frozen --all-extras --dev` succeeds, pyjwt 2.13.0 imports against typing-extensions 4.16.0 and signs a token, and the full pytest suite passes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8e74a4a to
439ff48
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4536 +/- ##
==========================================
- Coverage 93.46% 93.20% -0.26%
==========================================
Files 887 1042 +155
Lines 77424 88262 +10838
Branches 12426 14256 +1830
==========================================
+ Hits 72364 82267 +9903
- Misses 3021 3623 +602
- Partials 2039 2372 +333 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
theagenticguy
left a comment
There was a problem hiding this comment.
Reviewed the diff, the PR description's claims, and CI. Approving — the fix is correct, minimal, and independently verifiable.
What we verified:
- The diff is exactly what it claims: 11 lockfiles, one line each, dropping the
version/sourcepin from pyjwt'styping-extensionsdependency edge and leaving the bare marker-qualified edge — the canonical form uv emits when a lock holds a single version of the package. - Each of the 11 lockfiles on the PR head contains exactly one
typing-extensionsstanza (4.16.0), so the bare edge resolves unambiguously. The pinned edges onmain(4.13.2/4.14.0) point at versions with no[[package]]stanza, which is precisely the parse error uv reports. - No resolved versions change:
typing-extensions 4.16.0was already the only locked version, and it satisfies pyjwt 2.13.0's actual requirement (typing_extensions>=4.0; python_version < "3.11"per PyPI metadata). This restores parseability without any dependency drift. - CI is green on all 11 affected
Build <server>jobs (both workflow runs), plus the deeperBuild src/<server>jobs — the exact step that was failing onmain.
The root-cause analysis (Dependabot's surgical lock edit emitting a forked-style pinned edge into a single-version lock) is sound, and the textual repair is the right call given uv lock can't re-resolve a file it can't parse.
The follow-up suggestion — running uv sync --frozen on changed lock directories in Dependabot PRs — is worth an issue so this class of breakage gets caught pre-merge rather than on main.
No inline comments; the 11 hunks are identical in form and all correct.
Fixes the
Install dependenciesbuild failure introduced by #4503 (merged as a7b3263).Summary
Changes
Dependabot #4503 bumped
pyjwt2.10.1 → 2.13.0 across 30 directories. pyjwt 2.13.0 introduced a new conditional dependency ontyping-extensionsforpython_full_version < '3.11'.Dependabot edits
uv.locksurgically rather than re-resolving, and in 11 of the 30 locks it wrote that new edge with an explicit version pin:In
uv.lock, a dependency edge carriesversion/sourceonly when the lock holds multiple forked versions of that package. Each of these 11 locks contains a singletyping-extensionsentry (4.16.0), so the pinned edge (4.13.2or4.14.0) pointed at a package with no[[package]]stanza. uv rejects the file at parse time:The remaining 19 locks received a bare edge and were unaffected — the failing set is exactly the pinned set.
Fix: drop the bogus
version/sourcepin so each edge binds to the single lockedtyping-extensions. This is the canonical form uv itself emits, and is exactly what the 19 healthy locks contain. One line per lockfile, 11 files.Note
uv lockcannot regenerate these files — it hits the same parse error before it can re-resolve, so the repair has to be textual. No resolved versions change:typing-extensions 4.16.0was already the only locked version, so this only restores the lock to a parseable state.Affected servers:
cloudwatch,documentdb,elasticache,finch,iam,memcached,prometheus,redshift,timestream-for-influxdb,valkey,well-architected-security.User experience
Before —
uv sync --frozen --all-extras --devfails for all 11 servers, soBuild <pkg>is red onmainand these servers cannot be installed from the committed lock:After — installs cleanly and CI goes green:
Verification
Reproduced the failure across all 30 touched directories, confirming exactly 11 fail and that they correspond 1:1 with the pinned-edge locks. After the fix, for all 11 servers on Python 3.10 (the version where the marker is active, and what CI pins via
.python-version):uv sync --frozen --all-extras --dev(the failing CI step)pyjwt2.13.0 imports againsttyping-extensions4.16.0 and signs a tokenuv run --frozen pytestNote on
uv lock --checkand two locally-flaky suitesuv lock --checkreports "needs to be updated" for these locks — but it does so for untouched packages too (aurora-dsql,postgres,aws-location), so that drift is pre-existing and repo-wide, not introduced here. The CI gate isuv sync --frozen, which passes.elasticacheandtimestream-for-influxdbeach showed 1 failure locally purely because a localAWS_PROFILEleaked intoSession(...)assertions. WithAWS_PROFILEunset (as in CI): 414 passed and 154 passed respectively.Follow-up (not in this PR)
This can recur on any Dependabot bump that introduces a new transitive dependency, since Dependabot may emit a pinned edge the host lock cannot satisfy. Worth considering a CI check that runs
uv sync --frozenon changed lock directories in the Dependabot PR itself, so the breakage is caught before merge rather than onmain.Checklist
If your change doesn't seem to apply, please leave them unchecked.
Is this a breaking change? (Y/N) N
RFC issue number:
Checklist:
Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.
🤖 Generated with Claude Code