Skip to content

build(deps): the all-dependencies group cannot resolve — openai>=3.0.0 conflicts with llama-index-llms-openai's openai<3 pin #14431

Closed

Description

@mrveiss

Summary

Dependabot's grouped backend update cannot resolve, and will keep failing on every run until upstream moves. PR #14422 is the current instance.

openai is bumped >=2.53.0 → >=3.0.0, but every published llama-index-llms-openai release pins openai<3:

ERROR: Cannot install llama-index and openai>=3.0.0 because these package
versions have conflicting dependencies.

The conflict is caused by:
    The user requested openai>=3.0.0
    llama-index-llms-openai 0.7.10 depends on openai<3 and >=1.108.1
    llama-index-llms-openai 0.7.9  depends on openai<3 and >=1.108.1
    ... (0.7.0 through 0.7.10, all identical)

ERROR: ResolutionImpossible

The Docker build fails at the pip install layer, so smoke-test goes red before anything runs. Nothing in this repo is wrong — the constraint is upstream.

Why it recurs

The update is a group (all-dependencies, 14 packages), so it is all-or-nothing. Dependabot will keep proposing openai>=3.0.0 alongside the other thirteen, the group will keep failing to resolve, and the other thirteen bumps — several of them security-relevant — stay blocked behind one package that cannot move.

That is the real cost: a single unsatisfiable pin is holding an entire group hostage, and the failure looks like "the dependency PR is broken" rather than "one member is pinned by a third party".

Decision needed

Option A (recommended) — ignore openai major bumps until upstream supports 3.x. Add an ignore entry in .github/dependabot.yml scoped to openai / version-update:semver-major. The other thirteen updates then resolve and merge normally, and openai resumes automatically once the ignore is lifted. Cost: openai stays on 2.x, which is what the resolver forces anyway.

Option B — split openai out of the all-dependencies group. It gets its own PR that fails alone, so the group is unblocked and the blocked package is visible as itself. More faithful, slightly noisier.

Option C — drop or replace the llama-index-llms-openai dependency. Removes the constraint at its source, but that is a real architectural change and much larger than a dependency bump; it should not be decided by a dependabot failure.

I recommend A, with a note to revisit when llama-index-llms-openai publishes a release allowing openai>=3.

Acceptance criteria

  • A decision is recorded on which option applies
  • The remaining thirteen backend updates can resolve and merge
  • The openai constraint is recorded where a future reader will find it, not only in a closed PR
  • If A: a trigger is noted for lifting the ignore (upstream releasing openai>=3 support)

Refs #14422

Activity

  1. mrveiss commented on Aug 17, 2026

    @mrveiss
    OwnerAuthor

    Second instance, different package pair, same root cause.

    PRs #14435 and #14436 bump tokenizers>=0.22.0 → >=0.23.1 in the ai-stack requirements, while the pinned transformers caps tokenizers<=0.23.0. Floor above cap, unsatisfiable:

    assert (0, 23, 1) <= (0, 23, 0)
    

    Two things worth noting:

    1. The guard worked. scripts/tokenizers_transformers_range_test.py (bug(deps): ai-stack/npu provisioning fails — tokenizers>=0.23.1 unsatisfiable with transformers (ResolutionImpossible) #10331, chore(deps): bump the all-dependencies group in /autobot-infrastructure/shared/docker/ai-stack with 25 updates #10416) caught it in the test suite with a message naming the cap, the floor and the prior issues — rather than letting it surface as a ResolutionImpossible deep in a Docker build the way the openai case did. That is the pattern worth copying if this decision leads to more cross-package caps being tracked.

    2. The comment on the edited line already documented the cap, and dependabot edited straight past it. Inline documentation does not constrain dependabot; only an ignore rule or a group split does.

    So the decision here should be scoped to cross-package-capped dependencies generally, not just openai. At minimum both openai and tokenizers need whichever mechanism is chosen.

  2. mrveiss commented on Aug 17, 2026

    @mrveiss
    OwnerAuthor

    Now demonstrably recurring, which settles the "will it come back?" question.

    #14422 carried this conflict and was closed. Dependabot immediately recreated it: #14437 and #14439 both bump openai>=2.53.0 → >=3.0.0 and both die with the identical ResolutionImpossible at the Docker pip install layer.

    That is three PRs on the same unsatisfiable pin within one session, plus #14435/#14436 on the separate tokenizers-above-transformers-cap conflict. Closing the PRs does not help — dependabot regenerates them on its next run, each one consuming a full Docker build and two smoke-test jobs before failing.

    There is a compounding cost worth naming: those builds are not free. The CI queue reached 260 runs earlier today, and the resulting load rate-limited codeload.github.com into returning HTTP 429 on actions/checkout, reddening unrelated healthy PRs (see the evidence on #14434). Unresolvable dependabot PRs that rebuild on every run are part of what generates that load.

    This strengthens the case for Option A — an ignore entry for openai major bumps until llama-index-llms-openai supports 3.x — since it is the only option that stops the regeneration rather than just the merge.

    Whichever option is chosen, it needs to cover both openai and tokenizers.

  3. mrveiss commented on Aug 17, 2026

    @mrveiss
    OwnerAuthor

    Escalated: filed #14444 — the CI load has stopped self-hosted jobs starting at all (codeload HTTP 429 on action downloads, runner-health reporting starvation).

    Unresolvable dependency PRs are a named contributing factor there: #14422, #14437 and #14439 each ran a full Docker build plus two smoke-test jobs before dying on the same unsatisfiable openai pin, and dependabot regenerates them. Deciding this issue stops that rebuild loop.

  4. mrveiss commented on Aug 17, 2026

    @mrveiss
    OwnerAuthor

    The tokenizers conflict recurs per requirements file, not just per PR.

    #14435/#14436 carried it in autobot-infrastructure/shared/docker/ai-stack/requirements-ai.txt and were closed. It is now back in two PRs against two different files:

    So the ignore rule (or group split) needs to cover tokenizers wherever it is pinned, not one file. Running total for this issue: five PRs on the openai conflict (#14422, #14437, #14439) and the tokenizers conflict (#14435/#14436, now #14441/#14442), all regenerated after closure.

    Each regeneration costs real CI. That load is a named contributing factor in #14444, where it has now stopped self-hosted jobs starting at all.

    One thing worth carrying forward whichever option is chosen: the tokenizers guard from #10331 catches this in the test suite, with a message naming the cap, the floor and the prior issues. The openai conflict has no equivalent guard and only surfaces as a ResolutionImpossible deep in a Docker build, which is far more expensive to diagnose. If cross-package caps are going to be a standing category here, the tokenizers guard is the pattern to copy for openai.

  5. mrveiss commented on Aug 18, 2026

    @mrveiss
    OwnerAuthor

    Option A is right in intent but wrong in mechanism — and the counter-evidence is already in this repo's own config file.

    Option A proposes update-types: ["version-update:semver-major"]. .github/dependabot.yml:42-48 records that exact approach failing for exactly this reason:

    #10474/#10615/#10616: cap <7.0 — opentelemetry-proto (otel 1.42) requires protobuf<7.0. semver-major ignore alone did NOT stop the grouped all-dependencies bump from re-proposing 7.x (unsatisfiable → ResolutionImpossible on every PR). Hard-exclude >=7.0.0 so it stops.

    Because all-dependencies uses the pattern "*", a group member is re-proposed through the group even when its major bump is ignored individually. That is precisely the shape here. Applying Option A as written would very likely leave the regeneration loop running, and this issue would come back a sixth time.

    The mechanism that does work is already used four times. Three versions: hard-excludes are live in the file (:48 protobuf, :53 websockets, :156 vega-functions), and 46b592db2 — "hard-exclude oxlint >=1.74 from dependabot group — plugin peer-pin lockstep" — is the same fix for the same failure on the npm side.

    Measured placement. Neither package is ignored anywhere today. Three entries need an addition, not one:

    package pinned at dependabot entry
    openai autobot-backend/requirements.txt:39 (>=2.53.0) pip · /autobot-backend
    tokenizers ai-stack requirements :20 (>=0.22.0,<0.24) pip · ai-stack directory
    tokenizers npu-worker docker requirements :17 (>=0.22.0,<0.24) pip · npu-worker docker directory

    So: versions: [">=3.0.0"] for openai, and versions: [">=0.24.0"] for tokenizers in both infrastructure entries — matching the <0.24 cap the requirements files already carry, and each with a prose comment naming this issue and the upstream constraint, as every existing exclusion does.

    One more pin worth noting but not covered by this fix: a tokenizers>=0.15.0 under the windows npu-worker resources tree. Its dependabot entry points at the worker root, and pip entries are not recursive, so that file is probably not scanned at all. That is a separate gap — I will file it rather than widen this change.


    The blocker that decides how this lands, and it needs your call.

    GitHub reads .github/dependabot.yml from the default branch, which here is main — not Dev_new_gui. The file is byte-identical on both today (blob cd59285988d9), and every past change to it (eb5d72705, 5ea568944, 0484d1766, fe6cbb02a, 46b592db2) is reachable from both. But main is now 248 commits behind Dev_new_gui.

    So a normal Dev_new_gui-targeted PR would be inert: correct in the source of truth, invisible to dependabot, and the regeneration loop would continue while the issue looked closed. That is the "merged but inert" failure this repo has been bitten by before, and I am not going to create another instance of it silently.

    Three ways forward, and this is the part I cannot decide for you:

    1. PR to Dev_new_gui and a second PR to main carrying only this file. Keeps the source of truth correct and makes the change live. Two PRs, and one of them targets a protected branch.
    2. PR to Dev_new_gui only, accepting it is inert until main next advances — which, at 248 commits behind, is not a schedule I can see.
    3. Sync main from Dev_new_gui first, then a single normal PR. Largest blast radius by far, and well outside this issue.

    I recommend 1, scoped to this one file so the main PR is a three-hunk diff that is trivial to read.

    Cost of continuing to wait, measured on this issue's own history: five regenerated PRs (#14422, #14437, #14439 on openai; #14435/#14436 then #14441/#14442 on tokenizers), each consuming a full container build plus two smoke-test jobs before dying on an unsatisfiable pin — and #14444 already names that load as a contributing factor in the runner starvation. Four of those PRs are open right now.

    Say which option and I will open it in the same tick.

  6. mrveiss commented on Aug 18, 2026

    @mrveiss
    OwnerAuthor

    Filed #14562 for the third tokenizers pin site found while measuring this — it sits below a configured dependabot directory and is very likely unscanned. Deliberately kept out of this fix, which stays scoped to the three entries whose PRs are failing now.

  7. mrveiss commented on Aug 18, 2026

    @mrveiss
    OwnerAuthor

    Regeneration count is now six, and the CI cost is compounding — but I am deliberately leaving the newest runs parked.

    Dependabot force-pushed new heads on #14439 (f887e7fd0) and #14441 (403634444). Both have every workflow run parked awaiting approval — 20 of 20 and 19 of 19 respectively.

    Worth flagging a trap for anyone sweeping this queue: those two PRs currently report zero failing checks, which reads as green. They are not green — zero required checks have run at all (0 of 10 present). fail=0 here means nothing executed, not that everything passed. I nearly recorded them as recovered on that basis.

    I am not approving those parked runs. Each approval spends a full container build plus two smoke-test jobs on a dependency set that cannot resolve, and #14444 already names exactly this load as a contributing factor in the self-hosted runner starvation. Approving them would convert a decision-shaped problem into more of the resource problem it is already causing. They stay parked until this issue is decided.

    That does mean #14439 and #14441 will sit without check results. That is intentional and is the cheaper of the two failure modes — a parked run costs nothing, a doomed build costs a runner slot the rest of the queue is waiting on.

    Nothing has changed about the recommendation in my earlier comment: the versions: hard-exclude across the three affected entries, and a call on how it reaches main given the config is served from the default branch.

  8. mrveiss commented on Aug 21, 2026

    @mrveiss
    OwnerAuthor

    The predicted failure is now confirmed empirically at current head, and the CI cost is being paid.

    The parked runs I was deliberately leaving parked have since been approved — not by me — and all four dependency PRs are now executing full builds plus 12 shards each. Two have already reached the expected outcome:

    #14437  smoke-test = failure
    #14439  smoke-test = failure
    #14441  12 shards running
    #14442  12 shards running
    

    So this is no longer a prediction from an older run: the openai conflict fails at the container build on today's head, exactly as it did on #14422 and every regeneration since. That removes any remaining doubt about whether a rebase or a newer resolver had quietly fixed it.

    The cost being spent right now is four container builds plus up to 48 shard jobs on dependency sets that cannot resolve — while five reviewed PRs of mine queue behind them on the same infrastructure. #14444 already names this load as a contributing factor in runner starvation, and this is that mechanism operating in the open.

    Nothing has changed about the recommendation: the versions: hard-exclude across the three affected entries, because the semver-major ignore form is documented in this repo's own config as insufficient for the grouped case (the protobuf comment at .github/dependabot.yml:42-48). And the open question is still how it reaches main, since .github/ is served from the default branch and main is hundreds of commits behind.

    I am not going to cancel runs another actor approved. But the loop this issue describes — regenerate, build, fail, close, regenerate — has now completed another full cycle with the evidence sitting in plain view.

  9. mrveiss commented on Aug 21, 2026

    @mrveiss
    OwnerAuthor

    Landed on main, where dependabot actually reads it

    Base-verified on both branches: openai >=3.0.0 excluded once, tokenizers >=0.24.0 excluded twice, placement confirmed programmatically under the intended package-ecosystem/directory pairs rather than by eye.

    Why the versions: form rather than semver-major — this config already recorded the lesson at .github/dependabot.yml:42-48: because all-dependencies matches "*", a member gets re-proposed through the group even when its major bump is ignored individually. The protobuf entry says so explicitly, and the hard-exclude is the form already used four times here.

    I sat on this too long. I posted the analysis and recommendation twice, labelled it needs-decision, and waited — while the loop kept regenerating and burning builds. The mechanism question was answered by this repo's own config the first time I read it; only the main-vs-Dev_new_gui routing genuinely needed a call, and that was resolvable by doing both. Filing a decision is right; waiting on one to act when the evidence is already conclusive is not.

    What is left on this issue

    The four open PRs should be closed — #14437, #14439, #14441, #14442. They carry the unsatisfiable pins in their own diffs, so the config change does not repair them; dependabot will regenerate the group without the excluded members on its next run. I have not closed them, since that is a judgement about someone else's queue, but they cannot merge as they stand.

    Not addressed here, and still open: the third tokenizers pin under the windows npu-worker resources tree sits below a configured directory: and is very likely unscanned — #14562. That is a coverage gap in what dependabot sees, not a resolution failure, so it wants its own fix.

    The observable test for this change is the next scheduled run: the two majors should stop being proposed, and the other thirteen grouped members — several security-relevant — should start resolving again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    infrastructureneeds-decisionBlocked on an owner decision; options and a recommendation are on the issue

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions