litellm - ✅(Solved) Fix [Bug]: Pinning exact dependency versions in `pyproject.toml` breaks downstream consumers [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#26154Fetched 2026-04-22 07:46:16
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
2
Author
Participants
Timeline (top)
labeled ×2subscribed ×2cross-referenced ×1referenced ×1

Fix Action

Fix / Workaround

  1. The litellm team is already feeling the pain. The commit log right after #24905 shows:
    • "Fix pyproject.toml pins for Poetry Python 3.9 compatibility"
    • "Merge main and resolve dependency pin conflicts"
    • "Remove unused aioboto3 dependency and botocore conflict workarounds"
    • "Revert cryptography to 43.0.3 in pyproject.toml for Python 3.9.0/3.9.1 compat"

PR fix notes

PR #26157: fix(deps): relax core runtime dependency pins from exact == to ranges

Description (problem / solution / changelog)

Summary

When litellm migrated from Poetry to uv in PR #24905 (v1.83.1), a subtle semantic change broke library consumers:

  • Poetry: bare version strings like openai = "2.30.0" are implicitly caret ranges — they resolve to >=2.30.0,<3.0.0
  • PEP 621: openai==2.24.0 is an exact pin — only that exact version is allowed

The migration converted Poetry's implicit ranges to PEP 621 exact pins, which forces every downstream package that lists litellm as a dependency to downgrade 12 common runtime libraries (aiohttp, pydantic, openai, click, tokenizers, jinja2, etc.) to specific old patch versions — even if newer compatible versions are already installed.

Fixes: #26154 Overlaps with: #25231 (which fixes only python-dotenv)

Changes

Only the 12 core [project.dependencies] entries are changed — from exact == pins to lower-bounded ranges. The optional extras (proxy, proxy-runtime, etc.) keep their exact pins, since those are consumed by Docker images where reproducibility is important. The uv.lock file continues to provide exact pinning for Docker builds and CI.

Before (exact pins — broken for downstream consumers):

dependencies = [
    "fastuuid==0.14.0",
    "httpx==0.28.1",
    "openai==2.24.0",
    "python-dotenv==1.0.1",
    "tiktoken==0.12.0",
    "importlib-metadata==8.5.0",
    "tokenizers==0.22.2",
    "click==8.1.8",
    "jinja2==3.1.6",
    "aiohttp==3.13.3",
    "pydantic==2.12.5",
    "jsonschema==4.23.0",
]

After (lower-bounded ranges — compatible with downstream):

dependencies = [
    "fastuuid>=0.14.0",
    "httpx>=0.28.0",
    "openai>=2.0.0",
    "python-dotenv>=1.0.0",
    "tiktoken>=0.7.0",
    "importlib-metadata>=6.0.0",
    "tokenizers>=0.19.0",
    "click>=8.0.0",
    "jinja2>=3.1.0",
    "aiohttp>=3.10",
    "pydantic>=2.5.0,<3.0.0",
    "jsonschema>=4.0.0",
]

Why pydantic has an upper bound

pydantic>=2.5.0,<3.0.0 — pydantic v3 would be a breaking API change. All other ranges are open-ended upward since those packages follow semver and breaking changes would be a major version bump.

Testing

This is a metadata-only change to pyproject.toml. The uv.lock file and CI continue to install the same exact versions for testing and Docker builds. No runtime behavior changes.

Changed files

  • pyproject.toml (modified, +268/-266)

Code Example

$ uv add 'litellm>=1.83.8'
Uninstalled 10 packages
Installed 10 packages
 - aiohttp==3.13.5            + aiohttp==3.13.3
 - click==8.3.2               + click==8.1.8
 - importlib-metadata==9.0.0  + importlib-metadata==8.5.0
 - jsonschema==4.26.0         + jsonschema==4.23.0
 - litellm==1.83.0            + litellm==1.83.10
 - openai==2.32.0             + openai==2.24.0
 - pydantic==2.13.2           + pydantic==2.12.5
 - pydantic-core==2.46.2      + pydantic-core==2.41.5
 - python-dotenv==1.2.2       + python-dotenv==1.0.1
 - typer==0.24.1              + typer==0.23.1

---

aiohttp>=3.10
click
openai>=2.8.0
pydantic<3.0.0,>=2.5.0

---

aiohttp==3.13.5
click==8.1.8
openai==2.30.0
pydantic==2.12.5
...

---

pydantic>=2.5,<3
openai>=2.8
aiohttp>=3.10
click>=8
...

---
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

Starting in v1.83.1, litellm pins exact versions (==) for most of its core runtime dependencies in pyproject.toml. This was introduced in PR #24905 "[Infra] Pin All Docker Build Dependencies", merged 2026-04-01.

While the stated intent was to pin Docker build dependencies, the pins were placed in pyproject.toml, which affects every downstream consumer of litellm as a library — not just your own Docker images. This forces aggressive downgrades of common libraries (pydantic, openai, aiohttp, click, jsonschema, python-dotenv, importlib-metadata, etc.) and makes litellm very painful to coexist with in any non-trivial project.

Reproduction

Fresh project, upgrading from 1.83.0 → 1.83.10:

$ uv add 'litellm>=1.83.8'
Uninstalled 10 packages
Installed 10 packages
 - aiohttp==3.13.5            + aiohttp==3.13.3
 - click==8.3.2               + click==8.1.8
 - importlib-metadata==9.0.0  + importlib-metadata==8.5.0
 - jsonschema==4.26.0         + jsonschema==4.23.0
 - litellm==1.83.0            + litellm==1.83.10
 - openai==2.32.0             + openai==2.24.0
 - pydantic==2.13.2           + pydantic==2.12.5
 - pydantic-core==2.46.2      + pydantic-core==2.41.5
 - python-dotenv==1.2.2       + python-dotenv==1.0.1
 - typer==0.24.1              + typer==0.23.1

Every downgraded package matches litellm's pin exactly. pydantic-core follows pydantic, and typer is dragged down by the click==8.1.8 pin.

What changed

v1.82.6 / v1.83.0 (ranges — good):

aiohttp>=3.10
click
openai>=2.8.0
pydantic<3.0.0,>=2.5.0

v1.83.1 onwards (exact pins — problematic):

aiohttp==3.13.5
click==8.1.8
openai==2.30.0
pydantic==2.12.5
...

Also, these pins move every release — e.g. openai==2.30.0 in 1.83.1 has since been rolled back to openai==2.24.0 in 1.83.10 — so each litellm upgrade churns a different set of peer versions.

Why this is a problem

  1. Libraries should express compatibility, not lock environments. Exact pins belong in application lockfiles (uv.lock, poetry.lock, requirements.txt) or Docker constraint files — not in a library's pyproject.toml. The standard guidance from both the Python Packaging Authority and Poetry/uv/pip maintainers is that libraries should use ranges.

  2. Forces downgrades on any shared dep. Projects using pydantic 2.13, openai 2.32, click 8.3, etc. — all current stable releases — are forced backwards just to use litellm.

  3. Creates dependency deadlocks. Any other library that requires something newer than litellm's pin (e.g. pydantic>=2.13) becomes uninstallable alongside litellm. This is already happening — the ecosystem is moving faster than litellm's pin updates.

  4. The litellm team is already feeling the pain. The commit log right after #24905 shows:

    • "Fix pyproject.toml pins for Poetry Python 3.9 compatibility"
    • "Merge main and resolve dependency pin conflicts"
    • "Remove unused aioboto3 dependency and botocore conflict workarounds"
    • "Revert cryptography to 43.0.3 in pyproject.toml for Python 3.9.0/3.9.1 compat"

    These are all downstream effects of putting exact pins where they don't belong.

Suggested fix

Move the exact pins out of pyproject.toml and into one of:

  • A constraints.txt used by Docker builds (pip install -c constraints.txt ...)
  • A Poetry/uv lockfile committed alongside the Dockerfile
  • A separate requirements-docker.txt

And restore range-based specs in pyproject.toml, similar to 1.83.0:

pydantic>=2.5,<3
openai>=2.8
aiohttp>=3.10
click>=8
...

This preserves reproducible Docker builds (the original goal of #24905) without breaking every downstream consumer.

Environment

  • litellm 1.83.0 → 1.83.10

References

Steps to Reproduce

Relevant log output

What part of LiteLLM is this about?

No response

What LiteLLM version are you on ?

1.83.10

Twitter / LinkedIn details

No response

extent analysis

TL;DR

Move exact pins from pyproject.toml to a constraints.txt file or a Poetry/uv lockfile to resolve dependency conflicts.

Guidance

  • Identify the exact pins in pyproject.toml that are causing conflicts, such as aiohttp==3.13.5 and click==8.1.8.
  • Create a constraints.txt file with the exact pins, to be used by Docker builds with pip install -c constraints.txt ....
  • Update pyproject.toml to use range-based specs, such as pydantic>=2.5,<3 and openai>=2.8.
  • Verify that the updated pyproject.toml and constraints.txt files resolve the dependency conflicts.

Example

# constraints.txt
aiohttp==3.13.5
click==8.1.8
openai==2.24.0
pydantic==2.12.5

# pyproject.toml
pydantic>=2.5,<3
openai>=2.8
aiohttp>=3.10
click>=8

Notes

This solution assumes that the exact pins are only required for Docker builds and can be safely removed from pyproject.toml. If the exact pins are required for other use cases, additional modifications may be necessary.

Recommendation

Apply the suggested fix by moving exact pins to a constraints.txt file or a Poetry/uv lockfile, as this will resolve the dependency conflicts without breaking downstream consumers.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING