Skip to content

chore(security): bump langchain-core 0.3.45 -> 1.6.1 (9 advisories) - MAJOR, needs review - #11

Open
benfrank241 wants to merge 1 commit into
mainfrom
chore/security-daily-20260902-integrations-python-uv-langchain-core
Open

chore(security): bump langchain-core 0.3.45 -> 1.6.1 (9 advisories) - MAJOR, needs review#11
benfrank241 wants to merge 1 commit into
mainfrom
chore/security-daily-20260902-integrations-python-uv-langchain-core

Conversation

@benfrank241

Copy link
Copy Markdown
Member

Security: langchain-core 0.3.45 -> 1.6.1 — clears 9 advisories, but this is a MAJOR bump

⚠️ Read the "What to weigh" section before merging. This is a major-version bump of this package's primary dependency and it pulls in 13 new transitive packages. It is split out from #10 precisely so it can be judged on its own.

Why this is a hand-authored branch, not a Dependabot PR

Dependabot alerts are not running on this repo. GET /repos/vectorize-io/integrations-python/dependabot/alerts returns HTTP 200 with an empty array in every state (open, fixed, dismissed, auto_dismissed) despite a committed langchain/uv.lock — the repo has never been scanned. There are no alert numbers to close, so the advisories below are identified by GHSA/CVE only. They were found locally with:

uv export --frozen --no-emit-project --format requirements-txt -o req.txt
uvx pip-audit -r req.txt --no-deps

Recommendation: enable Dependabot alerts under Settings -> Code security.

Change — langchain/uv.lock only

pyproject.toml is not modified; its constraint is already langchain-core>=0.3.45, so nothing changes for downstream consumers of langchain-vectorize. This only moves what CI resolves and tests against.

uv lock --upgrade-package langchain-core

Because requires-python = ">=3.9", the lock has two resolution legs:

package py>=3.10 leg py3.9 leg
langchain-core 0.3.45 -> 1.6.1 0.3.45 -> 0.3.86
langsmith 0.3.15 -> 0.12.1 0.3.15 -> 0.4.37

Advisories cleared (py3.10-3.13; this is where the CI matrix mostly lives)

langchain-core — all 6:

langsmith — all 3:

After this change the py3.13 leg reports zero findings for langchain-core and langsmith. (11 findings remain in urllib3/requests/orjson/pytest — those are #10's job, not this PR's.)

What to weigh

1. Only 1.x can clear all six. The 0.3.x line tops out at 0.3.86, which still carries GHSA-qh6h-p6c9-ff54 (fix: 1.2.22) and GHSA-2g6r-c272-w58r (fix: 1.2.11) — neither was ever backported. There is no non-major path.

2. 13 new transitive packages. All verified as legitimate upstream projects, not typosquats:

added pulled in by provenance
langchain-protocol 0.0.19 langchain-core 1.6.1 github.com/langchain-ai/agent-protocol
uuid-utils langchain-core 1.6.1 + langsmith
httpx2, httpcore2, httpx2-jsfetch langsmith 0.12.1 (httpx2>=2,<3) github.com/pydantic/httpx2 — the httpx successor
truststore httpx2 / httpcore2
distro, websockets, xxhash langsmith 0.12.1

h11, httpcore, idna, anyio and typing-extensions also move on the py>=3.10 leg, dragged by httpx2 (which requires idna>=3.18 and h11>=0.16). That overlaps #10 — see "Interaction with #10" below.

3. The API surface actually used is tiny and stable. langchain_vectorize/retrievers.py imports exactly two things from langchain-core:

from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever

Both are present and unchanged in 1.x, and mypy --strict passes against 1.6.1.

4. The py3.9 leg is a smaller win and includes one regression. It gets langchain-core 0.3.86 (4 of 6 cleared) and langsmith 0.4.37, which introduces GHSA-v34v-rq6j-cj6p (CVE-2026-25528) — introduced in langsmith 0.4.10, fixed in 0.6.3, and 0.6.3 requires py>=3.10. langchain-core 0.3.86 requires langsmith>=0.3.45, so langsmith cannot stay at 0.3.15 once langchain-core moves. Net for the py3.9 leg is 23 -> 20 findings; net for py3.10-3.13 is 23 -> 11.

As in #10, the clean fix for the 3.9 leg is dropping Python 3.9 (EOL since October 2025) from requires-python, the classifiers and the CI matrix. That collapses the two legs into one and makes 1.x the only resolution. Maintainer's call — not attempted here.

Interaction with #10

Both PRs touch langchain/uv.lock, so whichever merges second needs a rebase and a re-run of uv lock — a mechanical fix, no decisions involved. They are otherwise independent: #10 covers urllib3/requests/idna/orjson/h11/pytest and does not touch langchain-core; this PR does not touch pytest/urllib3/requests/orjson. Merging #10 first is the lower-risk order.

Verification (both ends of the CI matrix)

Commands derived from .github/workflows/python_test.yml and lint.yml, run under langchain/:

step py3.9 py3.13
uv sync --dev pass pass
uv run ruff format --check pass pass
uv run ruff check pass pass
uv run mypy . pass pass
uv run pytest tests (collection) 2 collected 2 collected
uv run pytest tests (execution) not runnable locally not runnable locally

tests/test_retrievers.py is a live integration suite; its session fixture raises ValueError: Please set the VECTORIZE_TOKEN environment variable without repository secrets. This fails identically on unmodified main — environmental, not a regression. Real execution comes from this PR's own CI run, which is the whole reason for a hand-authored branch (Dependabot branches do not receive secrets). Given this is a major bump, the CI result here is the load-bearing signal — please do not merge until the integration tests are green.


Opened by the daily security sweep. Not to be merged automatically - please review.

…v.lock

Lockfile-only scoped regeneration (uv lock --upgrade-package langchain-core).
Clears 6 langchain-core and 3 langsmith advisories on the py>=3.10 resolution leg.
MAJOR version bump of the package's primary dependency - needs human review.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@benfrank241

Copy link
Copy Markdown
Member Author

CI triage: both red checks are pre-existing and unrelated to this change

CI is red, but neither failure is caused by anything in this PR. Both reproduce with the dependency versions this branch does not touch, and both hit PR #10 and PR #11 identically. Evidence below so a reviewer does not have to re-derive it.

1. LangChain Unit Tests (all 5 matrix legs) — HTTP 402 from the Vectorize API

vectorize_client.exceptions.ApiException: (402)
Reason: Payment Required
HTTP response body: {"success":false,"error":"Upgrade Required",
  "message":"API access is available on paid plans only. Please upgrade to use this endpoint.",
  "code":"UPGRADE_REQUIRED"}
.venv/lib/python3.13/site-packages/vectorize_client/exceptions.py:162: ApiException
  • It is an ERROR at setup, not a test assertion — it happens in the session-scoped fixture in tests/test_retrievers.py, before any code under test runs.
  • The secrets are present and valid: a missing/invalid VECTORIZE_TOKEN returns 401, and locally without the secret the fixture raises ValueError: Please set the VECTORIZE_TOKEN environment variable. Getting a 402 means it authenticated and was rejected on plan/billing, not credentials.
  • Identical on py3.9 and py3.13, i.e. on both resolution legs of the lock — so it is independent of which package versions resolved.
  • Action for a maintainer: the Vectorize account backing VECTORIZE_TOKEN needs API access restored on its plan. Until then this workflow cannot pass on any branch.

2. Lint LangChain (both legs) — pydantic-core 2.27.2 fails to build on Python 3.14

PYO3_ENVIRONMENT_SIGNATURE="cpython-3.14-64bit"
Error: command ['maturin', 'pep517', 'build-wheel', ...] returned non-zero exit status 1
hint: `pydantic-core` (v2.27.2) was included because `langchain-vectorize` (v0.0.3)
      depends on `vectorize-client` (v0.4.0) which depends on `pydantic` (v2.10.6)
      which depends on `pydantic-core`

Root cause is a latent bug in .github/workflows/lint.yml. It declares a matrix:

strategy:
  matrix:
    python-version: ['3.9', '3.13']

but then never uses matrix.python-version:

- uses: actions/setup-python@v5
  with:
    python-version-file: "langchain/pyproject.toml"

setup-python reads requires-python = ">=3.9" from that file and resolves it to the newest interpreter available — the log shows Successfully set up CPython (3.14.7). So both matrix legs install 3.14 regardless of the matrix, and pydantic-core 2.27.2 publishes no cp314 wheel, so uv falls back to a maturin/pyo3 source build that fails.

This is environment drift, not a code change: this repo last ran CI on 2025-09-01, before 3.14 existed on the runners. pydantic 2.10.6 and pydantic-core 2.27.2 are byte-identical to main on this branch — the only lines touching them in the diff are upload-time metadata and resolution markers, no version change.

Two independent fixes, both out of scope for a security bundle (mixing an unrelated lockfile or workflow change into a security PR is exactly what these bundles avoid):

  • python-version: ${{ matrix.python-version }} in lint.yml, so the matrix is actually honoured; and/or
  • bump pydantic/pydantic-core so a cp314 wheel exists.

Tracked in #12.

On the lockfile diff size

The diff is large (~750 added / ~590 removed lines) relative to 8 version changes. That is re-resolution metadata: this uv adds an upload-time = field to every lock entry it re-resolves. Verified not to be hidden dependency churn — a no-op uv lock on untouched main produces a byte-identical lockfile (0 changed lines), and the only version = lines in this diff are the packages named in the PR description.

What was verified locally

uv sync --dev, ruff format --check, ruff check, mypy . and pytest collection all pass on both py3.9 and py3.13. Test execution is impossible locally (and now, per #1 above, in CI too) because the suite is a live integration suite against a paid API.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant