Skip to content

fix(deps): repair uv.lock parse failure from pyjwt 2.13.0 bump (11 servers) - #4536

Merged
scottschreckengaust merged 1 commit into
mainfrom
fix/uv-lock-missing-typing-extensions
Aug 26, 2026
Merged

fix(deps): repair uv.lock parse failure from pyjwt 2.13.0 bump (11 servers)#4536
scottschreckengaust merged 1 commit into
mainfrom
fix/uv-lock-missing-typing-extensions

Conversation

@scottschreckengaust

Copy link
Copy Markdown
Member

Fixes the Install dependencies build failure introduced by #4503 (merged as a7b3263).

Summary

Changes

Dependabot #4503 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 edits 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 = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },

In uv.lock, a dependency edge carries version/source only when the lock holds multiple forked versions of that package. Each of these 11 locks contains a single typing-extensions entry (4.16.0), so the pinned edge (4.13.2 or 4.14.0) pointed at a package with no [[package]] stanza. uv rejects 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

The remaining 19 locks received a bare edge and were unaffected — the failing set is exactly the pinned set.

Fix: drop the bogus version/source pin so each edge binds to the single locked typing-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 lock cannot 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.0 was 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

Beforeuv sync --frozen --all-extras --dev fails for all 11 servers, so Build <pkg> is red on main and these servers cannot be installed from the committed lock:

$ cd src/iam-mcp-server && uv sync --frozen --all-extras --dev
error: Failed to parse `uv.lock`
  Caused by: For package `pyjwt==2.13.0 ...`, found dependency
             `typing-extensions==4.14.0` with no locked package

After — installs cleanly and CI goes green:

$ cd src/iam-mcp-server && uv sync --frozen --all-extras --dev
$ uv run --frozen pytest -q
174 passed in 2.18s

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):

Check Result
uv sync --frozen --all-extras --dev (the failing CI step) 11/11 pass
pyjwt 2.13.0 imports against typing-extensions 4.16.0 and signs a token 11/11 pass
uv run --frozen pytest 11/11 pass
Note on uv lock --check and two locally-flaky suites
  • uv lock --check reports "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 is uv sync --frozen, which passes.
  • elasticache and timestream-for-influxdb each showed 1 failure locally purely because a local AWS_PROFILE leaked into Session(...) assertions. With AWS_PROFILE unset (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 --frozen on changed lock directories in the Dependabot PR itself, so the breakage is caught before merge rather than on main.

Checklist

If your change doesn't seem to apply, please leave them unchecked.

  • I have reviewed the contributing guidelines
  • I have performed a self-review of this change
  • Changes have been tested
  • Changes are documented

Is this a breaking change? (Y/N) N

RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

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

…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>
@scottschreckengaust
scottschreckengaust force-pushed the fix/uv-lock-missing-typing-extensions branch from 8e74a4a to 439ff48 Compare August 25, 2026 19:53
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.20%. Comparing base (2a07bb8) to head (439ff48).
✅ All tests successful. No failed tests found.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@theagenticguy theagenticguy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the diff, the PR description's claims, and CI. Approving — the fix is correct, minimal, and independently verifiable.

What we verified:

  1. The diff is exactly what it claims: 11 lockfiles, one line each, dropping the version/source pin from pyjwt's typing-extensions dependency edge and leaving the bare marker-qualified edge — the canonical form uv emits when a lock holds a single version of the package.
  2. Each of the 11 lockfiles on the PR head contains exactly one typing-extensions stanza (4.16.0), so the bare edge resolves unambiguously. The pinned edges on main (4.13.2/4.14.0) point at versions with no [[package]] stanza, which is precisely the parse error uv reports.
  3. No resolved versions change: typing-extensions 4.16.0 was 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.
  4. CI is green on all 11 affected Build <server> jobs (both workflow runs), plus the deeper Build src/<server> jobs — the exact step that was failing on main.

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.

@scottschreckengaust
scottschreckengaust added this pull request to the merge queue Aug 26, 2026
Merged via the queue into main with commit 7d93d98 Aug 26, 2026
258 of 260 checks passed
@scottschreckengaust
scottschreckengaust deleted the fix/uv-lock-missing-typing-extensions branch August 26, 2026 02:17
@github-project-automation github-project-automation Bot moved this from To triage to Done in awslabs/mcp Project Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants