Repository navigation
Description
Description
.github/workflows/python-dependency-maintenance.yml runs weekly and has concluded success on every scheduled run since 2026-08-03. It has not, however, validated a single upper bound in that window. The Run dependency upper-bound validation step was skipped on all five runs, so no package's bounds have been maintained for five weeks while the workflow reported green.
Mechanism. The upper-bound step is gated on the preceding step's outcome:
- name: Run dependency bounds test scenarios
id: validate_bounds_test
continue-on-error: true # line 68
run: uv run poe validate-dependency-bounds-test --package "*"
- name: Run dependency upper-bound validation
id: validate_ranges
if: steps.validate_bounds_test.outcome == 'success' # line 74
run: uv run poe validate-dependency-bounds-project --mode upper --package "*"continue-on-error: true maps the failing step's conclusion to success (which is what the job status and the run badge report), while outcome stays failure — and outcome is what line 74 reads. The result is a run that looks green from the outside and silently does nothing.
Step outcomes per scheduled run (gh run view <id> --json jobs):
| Date | Run | Run dependency upper-bound validation |
|---|---|---|
| 2026-07-27 | 30239325494 | success — last time it ran |
| 2026-08-03 | 30786524929 | skipped |
| 2026-08-10 | 31355767987 | skipped |
| 2026-08-17 | 31993805435 | skipped |
| 2026-08-24 | 32689375667 | skipped |
| 2026-08-31 | 33356153685 | skipped |
Every one of those runs reports conclusion: success.
Root cause. The bounds test aborts on the first failing package, and since 2026-08-03 that is always packages/anthropic, always identically. agent_framework_anthropic/_vertex_client.py:23 imports google.auth.credentials under TYPE_CHECKING, but the package declares plain anthropic>=0.80.0,<0.117.0 (no [vertex] extra) and nothing in the repo declares google-auth. The isolated probe therefore has no google-auth to resolve and Pyright fails. The full workspace sync resolves google-auth transitively, which is why the normal poe pyright passes and this never shows up in local or PR CI.
This became a failure with #7342 (merged 2026-07-28), which narrowed probe surfaces so packages stop inheriting transitive extras such as core[all]. That was the right change; packages/core got a dependency-pyright escape hatch for exactly this situation, and packages/anthropic needed one and did not get it. The last passing run is 2026-07-27, the day before #7342 merged.
Why nobody was paged. The workflow's issue-creation step dedupes on title, and #6661 "Dependency bounds test failed" has been open and untouched since 2026-06-22, so each run logs Issue already exists and posts nothing. #6661's body describes a different, since-fixed packages/core failure.
Code Sample
Reproduces on a clean checkout of main. Note that --dry-run only prints the probe commands and cannot reproduce this; the real run is required.
cd python
uv run python -m scripts.dependencies.validate_dependency_bounds --mode test --package anthropicError Messages / Stack Traces
Local reproduction, byte-identical to the CI logs for all five runs:
packages\anthropic: lower failed
Task 'pyright' failed for packages\anthropic at resolution 'lowest-direct'.
_vertex_client.py:23:10 - error: Import "google.auth.credentials" could not be resolved (reportMissingImports)
_vertex_client.py:23:56 - error: Type of "GoogleCredentials" is unknown (reportUnknownVariableType)
_vertex_client.py:47:9 - error: Type of parameter "credentials" is partially unknown (reportUnknownParameterType)
_vertex_client.py:120:9 - error: Type of parameter "credentials" is partially unknown (reportUnknownParameterType)
4 errors, 0 warnings, 0 informations
CI, run 33356153685 (2026-08-31T04:11:42Z), same four errors:
packages/anthropic: lower failed
Task 'pyright' failed for packages/anthropic at resolution 'lowest-direct'.
/home/runner/work/.../agent_framework_anthropic/_vertex_client.py:23:10 - error:
Import "google.auth.credentials" could not be resolved (reportMissingImports)
Package Versions
agent-framework-anthropic 1.0.0b260827 (workspace main); the failure is workspace tooling, not a released package.
Python Version
3.13 (UV_PYTHON in the workflow); reproduced locally on 3.13.
Additional Context
I intend to implement this, using the documented extension point rather than a workaround — python/scripts/dependencies/README.md:49: "Uses a package-defined dependency-pyright task when present, allowing dependency probes to type-check the package implementation without requiring optional lazy namespace packages." The fix mirrors packages/core: a pyrightconfig.dependency.json plus a [tool.poe.tasks.dependency-pyright] entry, for packages/anthropic and packages/openai — the two packages whose failure is a probe artifact rather than a real defect (see the inventory below). Repo-wide Pyright is untouched and still checks every file in both packages in full.
What this unblocks. Those two fixes take the gate from 29/35 to 31/35; four real defects remain, listed below, and the gate will not go green until they are addressed too. Once it does, the upper-bound optimizer runs again and resumes maintaining bounds repo-wide. As a concrete example, this is what it picks for the fastapi ceiling in #8042 once it can run — the probe passes Pyright and the full test suite at fastapi 0.141.1:
$ uv run python -m scripts.dependencies._dependency_bounds_upper_impl \
--packages ag-ui --dependencies fastapi --dry-run
packages\ag-ui (agent-framework-ag-ui) :: fastapi :: baseline current_lower (lowest-direct) [0.121.0]
packages\ag-ui (agent-framework-ag-ui) :: fastapi :: baseline current_upper (highest) [0.139.2]
packages\ag-ui (agent-framework-ag-ui) :: fastapi -> <0.142.0 (probe 0.141.1)
That also confirms #7342's isolation fix works: the probe no longer inherits DevUI's fastapi<0.138.1, which is what produced the false conflict in #7339.
Follow-ups I am deliberately leaving out of the fix, as maintainer calls:
- The masking itself.
continue-on-error: trueplus anoutcome-gated successor means a five-week outage presents as five green runs. Whether the job should fail, or the gate should be restructured, is a decision about failure semantics I would rather not make unilaterally. - Stale-issue dedupe. Title-based dedupe against the long-open Dependency bounds test failed #6661 suppressed every alert. Closing Dependency bounds test failed #6661 restores alerting; making the dedupe smarter is a separate change.
- Both packages arguably under-declare an optional surface.
agent-framework-anthropicshipsAnthropicVertexClientwhile pinning plainanthropic>=0.80.0,<0.117.0(no[vertex]extra);agent-framework-openaisupports Entra ID auth while nothing declaresazure-identity. If either is meant to work out of the box, declaring the dependency (anthropic[vertex], an explicitazure-identity) is the real fix and the escape hatch could then be dropped. That changes a published dependency surface, so it needs a maintainer's call. - Raising the
fastapiceilings (Python: [Bug]: agent-framework-ag-ui caps fastapi<0.140.0, which excludes every current release #8042). Left to--mode upper, which is the component designed to choose and validate them. Note that devui (fastapi>=0.115.0,<0.138.1, a runtime dependency) — not ag-ui — is the binding constraint for anyone installing both;hosting-responsesdeclares fastapi under[dependency-groups] test, so it never constrains consumers. - First-failure abort.
_run_test_modeis sequential and returns on the first failing package, so one brittle package disables bounds maintenance for all 35 — and hides how many others are also broken. Establishing the inventory below required probing each package separately to work around it. Continuing past failures and reporting them together would have surfaced all six on 2026-08-03 instead of one.
The complete blocker inventory. Because the gate aborts on the first failure, fixing one package does not imply a green run — it just moves the abort. To get the real list rather than a lower bound, I probed all 35 packages individually (--mode test --package <name> per package, on Python 3.13 to match UV_PYTHON in the workflow). 29 pass, 6 fail; the fix I am preparing covers two of the six.
| Package | Task | Cause | Consumer impact |
|---|---|---|---|
anthropic |
pyright | TYPE_CHECKING import of undeclared google.auth |
none — probe artifact (covered by my fix) |
openai |
pyright | TYPE_CHECKING azure.core + lazy azure.identity, undeclared |
none — probe artifact (covered by my fix) |
declarative |
pyright | lazy runtime import of undeclared mcp |
ImportError on a normal install |
lab |
test | needs agent-framework-openai, declares only agent-framework-core |
ModuleNotFoundError |
azure-contentunderstanding |
pyright | to_llm_input(custom_metadata=…) absent at declared floor |
TypeError at the floor |
foundry_hosting |
test | one MCP test in test_responses.py fails at the floor |
behavioural break at the floor |
They divide cleanly.
Two are probe artifacts, and my fix covers both. anthropic and openai type-check against surfaces they deliberately do not declare because those surfaces are optional — openai's own docstrings say "Credential objects require the optional azure-identity package". A full workspace sync resolves them transitively, so repo-wide Pyright passes and only the isolated probe sees them missing. This is exactly the case dependency-pyright exists for.
Four are real defects that this gate existed to catch. Details for each:
declarativeunder-declaresmcp._mcp_handler.pyand_executors_mcp.pyimportmcplazily at runtime, and the code states the assumption outright —except ImportError: # pragma: no cover - mcp is a hard dep. Butpyproject.tomldeclaresagent-framework-core,httpx,powerfx,pyyamland nomcp;coredeclaresmcponly in itsallextra. So importing the package succeeds and executing its MCP executors raisesImportErrorfor anyone who installed it normally.labunder-declaresagent-framework-openai. Fails withModuleNotFoundError: No module named 'agent_framework_openai'— "the package agent-framework-openai is required to use…" — while declaring onlyagent-framework-core.azure-contentunderstandinghas a floor that never worked._context_provider.py:765callsto_llm_input(..., custom_metadata={"source": filename}); the declaredazure-ai-contentunderstanding>=1.2.0b2has no such parameter. The lower bound is not stale, it is wrong: installing at the floor gives aTypeErrorat call time.foundry_hostingfails a test at its floor. Consistently 1 failed / 285 passed atlowest-direct. Which MCP test intests/test_responses.pysurfaces varies between runs (the suite runs underpytest-xdistworksteal), and the validator truncates pytest output, so the precise assertion needs a direct run in the pinned environment.
declarative and lab are worth calling out together: both previously received their missing dependency through the core[all] leakage that #7342 removed. #7342 did not cause those two — it exposed them. They have been shipping under-declared, and the gate that would have said so has been dark since Aug 3.
I am not fixing the four here. They are different packages and different bounds, and two of them change a published dependency surface, which is a maintainer call. Filing them so the state of the gate is visible up front rather than surfacing one abort at a time, and because they are the concrete cost of five weeks without this gate.
Metadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
github-actions commentedon Sep 4, 2026
🤖 Automated triage reproduction notes (agent-authored — trust but verify)
Agent analysis
The outage occurs at
.github/workflows/python-dependency-maintenance.yml:66-76: a failed bounds probe remains green because ofcontinue-on-error, while its failure outcome skips upper-bound validation. The immediate trigger is the unresolvedgoogle.auth.credentialsimport atpython/packages/anthropic/agent_framework_anthropic/_vertex_client.py:23in the isolated environment. Minimal repro: frompython, runUV_PYTHON=3.13 uv run python -m scripts.dependencies.validate_dependency_bounds --mode test --package anthropic.python/scripts/dependencies/validate_dependency_bounds.py1.0.0b2608271.0.0b260827eavanvalkenburg commentedon Sep 9, 2026
The team is working on this workflow, but might drop it as Dependabot has been improving, closing this issue.