langchain-ai / langchain-ai/langgraph
langgraph-api: opentelemetry-exporter-prometheus<0.59 pin makes 0.11.0+ uninstallable with pydantic-ai 2.x / logfire>=4.16
- Dominant language
- Python
- Stars
- 41.8k
- Forks
- 7.1k
- Avg merge
- 23h 7m
- Merged PRs (30d)
- 30
Description
### Checked other resources
- [x] This is a bug, not a usage question.
- [x] I added a clear and descriptive title that summarizes this issue.
- [x] I used the GitHub search to find a similar question and didn't find it.
- [x] I am sure that this is a bug in LangGraph rather than my code.
- [x] The bug is not resolved by updating to the latest stable version of LangGraph (or the specific integration package).
- [x] This is not related to the langchain-community package.
- [x] I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.
### Related Issues / PRs
None found — GitHub search for `opentelemetry-exporter-prometheus` in this repo has no prior report of this conflict. (Issue 8089 is nearby but unrelated: a `0.12.0.dev` version-sync issue between `langgraph-api` and `langgraph-runtime-inmem`.)
### Reproduction Steps / Example Code (Python)
```python
# Dependency-resolution bug: no Python code required — this shell script is the
# complete reproduction. Requires only uv (tested with uv 0.11.28 on macOS and Linux).
mkdir -p repro && cd repro && cat > pyproject.toml <<'EOF'
[project]
name = "repro"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"langgraph-api==0.11.0",
"pydantic-ai>=2.8.0",
]
EOF
uv lock
# Expected: a successful resolution.
# Actual: "No solution found" — full output in the next field.
#
# The same conflict bites langgraph dev users indirectly: with
# langgraph-cli[inmem]>=0.4.31 and pydantic-ai in one project, resolution
# silently tops out at langgraph-api==0.10.3 and can never reach 0.11.0.
```
### Error Message and Stack Trace (if applicable)
```shell
Using CPython 3.14.6 interpreter at: /opt/homebrew/opt/python@3.14/bin/python3.14
× No solution found when resolving dependencies:
╰─▶ Because logfire>=4.35.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0 and opentelemetry-sdk>=1.39.0,<1.42.0, we can conclude that logfire[httpx]>=4.33.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because logfire==4.32.1 depends on opentelemetry-sdk>=1.39.0,<1.41.0, we can conclude that logfire[httpx]>=4.32.1 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because logfire>=4.16.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and only the following versions of logfire[httpx] are available:
logfire[httpx]<=4.16.0
logfire[httpx]==4.17.0
logfire[httpx]==4.18.0
logfire[httpx]==4.19.0
logfire[httpx]==4.20.0
logfire[httpx]==4.21.0
logfire[httpx]==4.22.0
logfire[httpx]==4.23.0
logfire[httpx]==4.24.0
logfire[httpx]==4.25.0
logfire[httpx]==4.26.0
logfire[httpx]==4.27.0
logfire[httpx]==4.28.0
logfire[httpx]==4.29.0
logfire[httpx]==4.30.0
logfire[httpx]==4.31.0
logfire[httpx]==4.31.1
logfire[httpx]==4.31.2
logfire[httpx]==4.32.0
logfire[httpx]==4.32.1
logfire[httpx]==4.33.0
logfire[httpx]==4.34.0
logfire[httpx]==4.35.0
logfire[httpx]==4.36.0
logfire[httpx]==4.37.0
we can conclude that logfire[httpx]>=4.16.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because pydantic-ai-slim[logfire]>=2.8.0 depends on logfire[httpx]>=4.16.0 and pydantic-ai==2.8.0 depends on pydantic-ai-slim[logfire]==2.8.0, we can conclude that pydantic-ai==2.8.0 depends on
opentelemetry-sdk>=1.39.0,<1.43.0. (1)
Because logfire>=4.35.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0 and opentelemetry-sdk>=1.39.0,<1.42.0, we can conclude that logfire[httpx]>=4.33.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because logfire==4.32.1 depends on opentelemetry-sdk>=1.39.0,<1.41.0, we can conclude that logfire[httpx]>=4.32.1 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because logfire>=4.16.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and only the following versions of logfire[httpx] are available:
logfire[httpx]<=4.16.0
logfire[httpx]==4.17.0
logfire[httpx]==4.18.0
logfire[httpx]==4.19.0
logfire[httpx]==4.20.0
logfire[httpx]==4.21.0
logfire[httpx]==4.22.0
logfire[httpx]==4.23.0
logfire[httpx]==4.24.0
logfire[httpx]==4.25.0
logfire[httpx]==4.26.0
logfire[httpx]==4.27.0
logfire[httpx]==4.28.0
logfire[httpx]==4.29.0
logfire[httpx]==4.30.0
logfire[httpx]==4.31.0
logfire[httpx]==4.31.1
logfire[httpx]==4.31.2
logfire[httpx]==4.32.0
logfire[httpx]==4.32.1
logfire[httpx]==4.33.0
logfire[httpx]==4.34.0
logfire[httpx]==4.35.0
logfire[httpx]==4.36.0
logfire[httpx]==4.37.0
we can conclude that logfire[httpx]>=4.16.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because pydantic-ai-slim[logfire]>=2.8.0 depends on logfire[httpx]>=4.16.0 and pydantic-ai==2.9.0 depends on pydantic-ai-slim[logfire]==2.9.0, we can conclude that pydantic-ai==2.9.0 depends on
opentelemetry-sdk>=1.39.0,<1.43.0.
And because we know from (1) that pydantic-ai==2.8.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0, we can conclude that pydantic-ai>=2.8.0,<=2.9.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because only the following versions of pydantic-ai are available:
pydantic-ai<=2.8.0
pydantic-ai==2.9.0
pydantic-ai==2.9.1
pydantic-ai==2.10.0
we can conclude that pydantic-ai>=2.8.0,<2.9.1 depends on opentelemetry-sdk>=1.39.0,<1.43.0. (2)
Because logfire>=4.35.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0 and opentelemetry-sdk>=1.39.0,<1.42.0, we can conclude that logfire[httpx]>=4.33.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because logfire==4.32.1 depends on opentelemetry-sdk>=1.39.0,<1.41.0, we can conclude that logfire[httpx]>=4.32.1 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because logfire>=4.16.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and only the following versions of logfire[httpx] are available:
logfire[httpx]<=4.16.0
logfire[httpx]==4.17.0
logfire[httpx]==4.18.0
logfire[httpx]==4.19.0
logfire[httpx]==4.20.0
logfire[httpx]==4.21.0
logfire[httpx]==4.22.0
logfire[httpx]==4.23.0
logfire[httpx]==4.24.0
logfire[httpx]==4.25.0
logfire[httpx]==4.26.0
logfire[httpx]==4.27.0
logfire[httpx]==4.28.0
logfire[httpx]==4.29.0
logfire[httpx]==4.30.0
logfire[httpx]==4.31.0
logfire[httpx]==4.31.1
logfire[httpx]==4.31.2
logfire[httpx]==4.32.0
logfire[httpx]==4.32.1
logfire[httpx]==4.33.0
logfire[httpx]==4.34.0
logfire[httpx]==4.35.0
logfire[httpx]==4.36.0
logfire[httpx]==4.37.0
we can conclude that logfire[httpx]>=4.16.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because pydantic-ai-slim[logfire]>=2.8.0 depends on logfire[httpx]>=4.16.0 and pydantic-ai==2.9.1 depends on pydantic-ai-slim[logfire]==2.9.1, we can conclude that pydantic-ai==2.9.1 depends on
opentelemetry-sdk>=1.39.0,<1.43.0.
And because we know from (2) that pydantic-ai>=2.8.0,<2.9.1 depends on opentelemetry-sdk>=1.39.0,<1.43.0, we can conclude that pydantic-ai>=2.8.0,<2.10.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0. (3)
Because only the following versions of logfire[httpx] are available:
logfire[httpx]<=4.16.0
logfire[httpx]==4.17.0
logfire[httpx]==4.18.0
logfire[httpx]==4.19.0
logfire[httpx]==4.20.0
logfire[httpx]==4.21.0
logfire[httpx]==4.22.0
logfire[httpx]==4.23.0
logfire[httpx]==4.24.0
logfire[httpx]==4.25.0
logfire[httpx]==4.26.0
logfire[httpx]==4.27.0
logfire[httpx]==4.28.0
logfire[httpx]==4.29.0
logfire[httpx]==4.30.0
logfire[httpx]==4.31.0
logfire[httpx]==4.31.1
logfire[httpx]==4.31.2
logfire[httpx]==4.32.0
logfire[httpx]==4.32.1
logfire[httpx]==4.33.0
logfire[httpx]==4.34.0
logfire[httpx]==4.35.0
logfire[httpx]==4.36.0
logfire[httpx]==4.37.0
and logfire>=4.16.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.17.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.17.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.19.0 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.19.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.21.0 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.21.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.23.0 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.23.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.25.0 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.25.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.27.0 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.27.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.29.0 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.29.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.31.0 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.31.0,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.31.2 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire>=4.31.2,<=4.32.0 depends on opentelemetry-sdk>=1.39.0,<1.40.0 and opentelemetry-sdk>=1.39.0,<1.40.0, we can conclude that logfire[httpx]>=4.16.0,<4.32.1 depends on
opentelemetry-sdk>=1.39.0,<1.40.0.
And because logfire==4.32.1 depends on opentelemetry-sdk>=1.39.0,<1.41.0 and opentelemetry-sdk>=1.39.0,<1.42.0, we can conclude that logfire[httpx]>=4.16.0,<4.34.0 depends on
opentelemetry-sdk>=1.39.0,<1.42.0.
And because logfire==4.34.0 depends on opentelemetry-sdk>=1.39.0,<1.42.0 and opentelemetry-sdk>=1.39.0,<1.43.0, we can conclude that logfire[httpx]>=4.16.0,<4.36.0 depends on
opentelemetry-sdk>=1.39.0,<1.43.0.
And because logfire>=4.36.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0 and opentelemetry-sdk>=1.39.0,<1.43.0, we can conclude that logfire[httpx]>=4.16.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because pydantic-ai-slim[logfire]==2.10.0 depends on logfire[httpx]>=4.16.0 and pydantic-ai==2.10.0 depends on pydantic-ai-slim[logfire]==2.10.0, we can conclude that pydantic-ai==2.10.0 depends on
opentelemetry-sdk>=1.39.0,<1.43.0.
And because we know from (3) that pydantic-ai>=2.8.0,<2.10.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0, we can conclude that pydantic-ai>=2.8.0 depends on opentelemetry-sdk>=1.39.0,<1.43.0.
And because opentelemetry-exporter-prometheus==0.58b0 depends on opentelemetry-sdk>=1.37.0,<1.38.dev0, we can conclude that opentelemetry-exporter-prometheus==0.58b0 and pydantic-ai>=2.8.0 are incompatible.
And because only the following versions of opentelemetry-exporter-prometheus are available:
opentelemetry-exporter-prometheus<=0.58b0
opentelemetry-exporter-prometheus>0.59
and langgraph-api==0.11.0 depends on opentelemetry-exporter-prometheus>=0.58b0,<0.59, we can conclude that langgraph-api==0.11.0 and pydantic-ai>=2.8.0 are incompatible.
And because your project depends on langgraph-api==0.11.0 and pydantic-ai>=2.8.0, we can conclude that your project's requirements are unsatisfiable.
hint: `opentelemetry-exporter-prometheus` was requested with a pre-release marker (e.g., opentelemetry-exporter-prometheus>0.58b0,<0.59), but pre-releases weren't enabled (try: `--prerelease=allow`)
```
### Description
#### The problem
The current `opentelemetry-exporter-prometheus` cap forces OTel SDK `~=1.37.0`, which cannot coexist with `logfire>=4.16` — and therefore with **any release of [pydantic-ai](https://github.com/pydantic/pydantic-ai) 2.x**. Consider widening `langgraph-api`'s `opentelemetry-exporter-prometheus>=0.58b0,<0.59` pin (e.g. to `<0.65`).
#### The root cause
| Package | Requires | Which forces |
| --- | --- | --- |
| `langgraph-api >=0.11.0` (incl. `0.12.0rc1`) | `opentelemetry-exporter-prometheus >=0.58b0,<0.59` | exporter `0.58b0` → `opentelemetry-sdk ~=1.37.0` |
| `pydantic-ai 2.x` (every release — the `logfire` extra and its floor date back to 2.0.0) | `pydantic-ai-slim[logfire]` → `logfire[httpx] >=4.16.0` | `opentelemetry-sdk >=1.39` (every logfire release since 4.16) |
`~=1.37.0` and `>=1.39` have no intersection, so any project containing both packages is unsatisfiable. uv pinpoints the conflict directly (output above); pip 26.x also fails, though it gives up with `resolution-too-deep` after exhaustive backtracking rather than naming the culprit.
#### What this breaks
* **`langgraph dev` users can never reach 0.11.0.** With `langgraph-cli[inmem]` and pydantic-ai in one project, resolution silently tops out at `langgraph-api==0.10.3` — the last release *without* the prometheus exporter dependency (it's new in 0.11.0).
* **Studio then asks those users to do the impossible.** The hosted Studio banner (text as of 2026-07) reads:
> Studio tracing requires langgraph-api 0.11.0 or later with session-name tracing enabled. Your server reports version 0.10.3. Upgrade and redeploy your agent server to restore in-Studio traces.
…but that upgrade cannot resolve for this class of projects.
* **The blast radius is wide**: any co-installation with pydantic-ai 2.x, with logfire >=4.16 directly, or with anything else on the OTel SDK >=1.39 line — where the ecosystem has been since late 2025.
#### Suggested fix
Widen the cap in `langgraph-api`'s dependency list (checked against the published sdist's `pyproject.toml`):
```toml
dependencies = [
# before
"opentelemetry-exporter-prometheus>=0.58b0,<0.59",
# after — lets the resolver pick the SDK line the rest of the tree needs
"opentelemetry-exporter-prometheus>=0.58b0,<0.65",
]
```
The exporter's betas pair 1-to-1 with SDK minors (`0.60b1 → ~=1.39.0`, `0.63b1 → ~=1.42.0`, `0.64b0` — latest — `→ ~=1.43.0`), so with a widened cap the resolver lands on whichever the rest of the tree needs — e.g. `0.63b1` alongside current logfire. Two supporting observations:
* `langgraph-api`'s *other* OTel dependencies (`opentelemetry-api`, `opentelemetry-sdk`, `opentelemetry-exporter-otlp-proto-http`) are already effectively unbounded (`>=0.0.1`) — the prometheus exporter is the single tight cap.
* `0.11.0.dev3` originally shipped this dependency **uncapped** at `>=0.62b1` (which would coexist fine today); the narrowing to `<0.59` arrived in `0.11.0.dev7`.
#### What we ruled out
* **Downgrading pydantic-ai** — the `logfire>=4.16` floor is present on every 2.x release back to 2.0.0; there is no compatible version on the line.
* **uv's trailing `--prerelease=allow` hint** — a dead end: pre-releases are already admitted for this pre-release-only package, and the `<0.59` cap excludes every exporter built against SDK >=1.39 regardless.
* **Resolver overrides** to force a newer exporter past the cap — works mechanically, but ignores what `langgraph-api` declares it was tested against; not something we'd run or recommend.
Happy to test a pre-release with the widened pin.
### System Info
Reproduces on any system — this is metadata arithmetic, not runtime behavior. Observed on:
```text
System Information
------------------
> OS: Darwin (arm64)
> OS Version: Darwin Kernel Version 25.5.0
> Python Version: 3.13.7
Package Information
-------------------
> langchain_core: 1.4.9
> langchain: 1.3.13
> langsmith: 0.10.2
> langgraph_api: 0.10.3 <- max reachable; 0.11.0 is the version under report
> langgraph_cli: 0.4.31
> langgraph_runtime_inmem: 0.30.3
> langgraph_sdk: 0.4.2
> langchain_anthropic: 1.4.8
> langchain_google_genai: 4.2.7
> langchain_openai: 1.3.5
Resolvers
---------
> uv: 0.11.28 (names the conflict; output above)
> pip: 26.x (also fails; reports resolution-too-deep rather than naming the conflict)
```
Contributor guide
Research direction
Start with the reproduced pyproject.toml dependency set and run uv lock to confirm the conflict between langgraph-api, pydantic-ai, logfire, and the OpenTelemetry packages. Inspect langgraph-api's dependency metadata; done when the stated dependency combination resolves successfully and the affected langgraph-cli[inmem] case can reach 0.11.0.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100