github-actions[bot]
381a9f64d0
chore: version packages ( #2445 )
...
This PR was opened by the [Changesets
release](https://github.com/changesets/action ) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## @langchain/langgraph-checkpoint@1.0.3
### Patch Changes
- [#2352 ](https://github.com/langchain-ai/langgraphjs/pull/2352 )
[`14f2a79`](https://github.com/langchain-ai/langgraphjs/commit/14f2a796912e81d7f52f0a4f16747f6d0a269209 )
Thanks [@Nagendhra-web](https://github.com/Nagendhra-web )! -
fix(langgraph-checkpoint): block prototype pollution in MemorySaver via
reserved storage keys
`MemorySaver` previously embedded `thread_id`, `checkpoint_ns`,
`checkpoint_id`, and `task_id` directly into property accesses on the
nested plain objects `this.storage` and `this.writes`. A caller able to
shape any of those fields (every quickstart, tutorial, and test fixture
uses `MemorySaver` by default) could pass `"__proto__"`,
`"constructor"`, or `"prototype"` and have the subsequent assignment
mutate `Object.prototype`. From that point every plain object in the
process inherits the injected property, breaking `for...in` loops,
truthy short-circuits, and downstream serializers across unrelated code
paths. CWE-1321.
Adds an `assertSafeStorageKey` chokepoint applied at every public entry
that touches `storage` or `writes` (`put`, `putWrites`, `deleteThread`,
`getTuple`, `list`). The guard rejects non-string values, the empty
string (unless explicitly opted-in for `checkpoint_ns`), and the three
prototype-pollution keys. Behaviour for valid string identifiers is
unchanged.
## @langchain/langgraph-checkpoint-redis@1.0.6
### Patch Changes
- [#2350 ](https://github.com/langchain-ai/langgraphjs/pull/2350 )
[`1e73c6b`](https://github.com/langchain-ai/langgraphjs/commit/1e73c6b4630bbc4aa976eea4bfc33c4f753b7ee9 )
Thanks [@Nagendhra-web](https://github.com/Nagendhra-web )! -
fix(checkpoint-redis): block Redis KEYS / SCAN pattern injection via
top-level identifiers
`RedisSaver` and `ShallowRedisSaver` previously embedded `thread_id`,
`checkpoint_ns`, `checkpoint_id`, and `task_id` directly into Redis keys
and `client.keys(pattern)` calls with no validation. A caller able to
shape any of those fields (multi-tenant SDK deployments where the
`RunnableConfig` originates from request input, or webhook payloads that
flow into a persisted thread) could promote a string identifier into a
glob pattern (`*`, `?`, `[...]`) or escape character (`\`).
The most severe sink is `deleteThread`: a `threadId` of `*` issues
`client.keys("checkpoint:*:*")` followed by `client.del(...)`, deleting
every checkpoint in the database across every tenant. `getTuple`,
`list`, and `loadPendingWrites` are exposed to the same pattern via
the fallback paths that bypass the existing `escapeRediSearchTagValue`
defense.
Adds a single `assertSafeKeyComponent` helper exported from
`./utils.js` and applies it at every key-building site. The guard
asserts the value is a non-empty string (the empty `checkpoint_ns`
default is opt-in via `{ allowEmpty: true }`) and rejects the Redis
pattern meta-characters `* ? [ ] \`. The `:` delimiter is intentionally
permitted because LangGraph emits it as a legitimate part of
`checkpoint_ns` for subgraphs / nested graphs, where it only ever
appears as a literal in the key. Behavior for valid string identifiers
is unchanged.
## @langchain/langgraph-api@1.2.3
### Patch Changes
- [#2447 ](https://github.com/langchain-ai/langgraphjs/pull/2447 )
[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: fold forkFrom client-side and honor per-run
multitaskStrategy
The SDK now folds the ergonomic `forkFrom` option into
`config.configurable.checkpoint_id` before sending `run.start`, so the
agent server only ever accepts the single, legacy-compliant fork field
(`forkFrom` no longer hits the wire). The protocol-v2 reference servers
drop their top-level `forkFrom` normalization accordingly.
The protocol-v2 servers now honor the caller's `multitaskStrategy` per
run (one of `reject` \| `rollback` \| `interrupt` \| `enqueue`) instead
of
hardcoding it, falling back to `enqueue` when omitted or unrecognized.
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
- [#2448 ](https://github.com/langchain-ai/langgraphjs/pull/2448 )
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: add `respondAll()` and run config/metadata on interrupt
resume
The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a
`respondAll(responsesById, options)` method to resume several interrupts
pending at the same checkpoint in a single command — required for runs
that
pause on multiple interrupts at once (e.g. parallel tool-authorization
prompts), which sequential `respond()` calls cannot handle.
`respond()` now takes an options object (`{ interruptId?, namespace?,
config?, metadata? }`) so a resumed run can carry the same run-level
config
(model, user context, …) and metadata (trigger source, test flags, …) a
fresh `submit()` would. The protocol-v2 reference servers read the new
`responses` batch and `config` / `metadata` fields leniently and fold
them
onto the run that services the `input.respond` command.
- Updated dependencies
\[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )]:
- @langchain/langgraph-ui@1.2.3
## @langchain/langgraph-cli@1.2.3
### Patch Changes
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
- Updated dependencies
\[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 ),
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/langgraph-api@1.2.3
## @langchain/langgraph-ui@1.2.3
### Patch Changes
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
## @langchain/langgraph-sdk@1.9.10
### Patch Changes
- [#2447 ](https://github.com/langchain-ai/langgraphjs/pull/2447 )
[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: fold forkFrom client-side and honor per-run
multitaskStrategy
The SDK now folds the ergonomic `forkFrom` option into
`config.configurable.checkpoint_id` before sending `run.start`, so the
agent server only ever accepts the single, legacy-compliant fork field
(`forkFrom` no longer hits the wire). The protocol-v2 reference servers
drop their top-level `forkFrom` normalization accordingly.
The protocol-v2 servers now honor the caller's `multitaskStrategy` per
run (one of `reject` \| `rollback` \| `interrupt` \| `enqueue`) instead
of
hardcoding it, falling back to `enqueue` when omitted or unrecognized.
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
- [#2448 ](https://github.com/langchain-ai/langgraphjs/pull/2448 )
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: add `respondAll()` and run config/metadata on interrupt
resume
The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a
`respondAll(responsesById, options)` method to resume several interrupts
pending at the same checkpoint in a single command — required for runs
that
pause on multiple interrupts at once (e.g. parallel tool-authorization
prompts), which sequential `respond()` calls cannot handle.
`respond()` now takes an options object (`{ interruptId?, namespace?,
config?, metadata? }`) so a resumed run can carry the same run-level
config
(model, user context, …) and metadata (trigger source, test flags, …) a
fresh `submit()` would. The protocol-v2 reference servers read the new
`responses` batch and `config` / `metadata` fields leniently and fold
them
onto the run that services the `input.respond` command.
## @langchain/angular@1.0.10
### Patch Changes
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
- [#2448 ](https://github.com/langchain-ai/langgraphjs/pull/2448 )
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: add `respondAll()` and run config/metadata on interrupt
resume
The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a
`respondAll(responsesById, options)` method to resume several interrupts
pending at the same checkpoint in a single command — required for runs
that
pause on multiple interrupts at once (e.g. parallel tool-authorization
prompts), which sequential `respond()` calls cannot handle.
`respond()` now takes an options object (`{ interruptId?, namespace?,
config?, metadata? }`) so a resumed run can carry the same run-level
config
(model, user context, …) and metadata (trigger source, test flags, …) a
fresh `submit()` would. The protocol-v2 reference servers read the new
`responses` batch and `config` / `metadata` fields leniently and fold
them
onto the run that services the `input.respond` command.
- Updated dependencies
\[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 ),
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/langgraph-sdk@1.9.10
## @langchain/react@1.0.10
### Patch Changes
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
- [#2448 ](https://github.com/langchain-ai/langgraphjs/pull/2448 )
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: add `respondAll()` and run config/metadata on interrupt
resume
The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a
`respondAll(responsesById, options)` method to resume several interrupts
pending at the same checkpoint in a single command — required for runs
that
pause on multiple interrupts at once (e.g. parallel tool-authorization
prompts), which sequential `respond()` calls cannot handle.
`respond()` now takes an options object (`{ interruptId?, namespace?,
config?, metadata? }`) so a resumed run can carry the same run-level
config
(model, user context, …) and metadata (trigger source, test flags, …) a
fresh `submit()` would. The protocol-v2 reference servers read the new
`responses` batch and `config` / `metadata` fields leniently and fold
them
onto the run that services the `input.respond` command.
- Updated dependencies
\[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 ),
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/langgraph-sdk@1.9.10
## @langchain/svelte@1.0.10
### Patch Changes
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
- [#2448 ](https://github.com/langchain-ai/langgraphjs/pull/2448 )
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: add `respondAll()` and run config/metadata on interrupt
resume
The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a
`respondAll(responsesById, options)` method to resume several interrupts
pending at the same checkpoint in a single command — required for runs
that
pause on multiple interrupts at once (e.g. parallel tool-authorization
prompts), which sequential `respond()` calls cannot handle.
`respond()` now takes an options object (`{ interruptId?, namespace?,
config?, metadata? }`) so a resumed run can carry the same run-level
config
(model, user context, …) and metadata (trigger source, test flags, …) a
fresh `submit()` would. The protocol-v2 reference servers read the new
`responses` batch and `config` / `metadata` fields leniently and fold
them
onto the run that services the `input.respond` command.
- Updated dependencies
\[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 ),
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/langgraph-sdk@1.9.10
## @langchain/vue@1.0.10
### Patch Changes
- [#2443 ](https://github.com/langchain-ai/langgraphjs/pull/2443 )
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom
Remove the misleading submit({ command }) surface from protocol-v2
StreamController; HITL resume is respond() only. Accept forkFrom as a
plain checkpoint id string and align protocol-v2 servers and docs.
- [#2448 ](https://github.com/langchain-ai/langgraphjs/pull/2448 )
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
protocol-v2: add `respondAll()` and run config/metadata on interrupt
resume
The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a
`respondAll(responsesById, options)` method to resume several interrupts
pending at the same checkpoint in a single command — required for runs
that
pause on multiple interrupts at once (e.g. parallel tool-authorization
prompts), which sequential `respond()` calls cannot handle.
`respond()` now takes an options object (`{ interruptId?, namespace?,
config?, metadata? }`) so a resumed run can carry the same run-level
config
(model, user context, …) and metadata (trigger source, test flags, …) a
fresh `submit()` would. The protocol-v2 reference servers read the new
`responses` batch and `config` / `metadata` fields leniently and fold
them
onto the run that services the `input.respond` command.
- Updated dependencies
\[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 ),
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/langgraph-sdk@1.9.10
## @example/ai-elements@0.1.25
### Patch Changes
- Updated dependencies
\[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/react@1.0.10
## @examples/assistant-ui-claude@0.1.25
### Patch Changes
- Updated dependencies
\[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/react@1.0.10
## @examples/ui-angular@0.0.35
### Patch Changes
- Updated dependencies
\[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 ),
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/langgraph-sdk@1.9.10
- @langchain/angular@1.0.10
## @examples/ui-multimodal@0.0.11
### Patch Changes
- Updated dependencies
\[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/react@1.0.10
## @examples/ui-react@0.0.11
### Patch Changes
- Updated dependencies
\[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9 ),
[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532 ),
[`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d )]:
- @langchain/langgraph-sdk@1.9.10
- @langchain/react@1.0.10
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-29 00:08:20 -07:00
Nagendhra Madishetti
1e73c6b463
fix(langgraph-checkpoint-redis): block KEYS / SCAN pattern injection via top-level identifiers ( #2350 )
...
## Summary
Closes a Redis pattern-injection sink (CWE-77, CWE-943) in `RedisSaver`
and `ShallowRedisSaver`. A caller able to shape `thread_id`,
`checkpoint_ns`, `checkpoint_id`, or `task_id` (multi-tenant SDK
deployments where the `RunnableConfig` originates from request input, or
webhook payloads that flow into a persisted thread) can promote a string
identifier into a Redis glob (`*`, `?`, `[...]`) and read, overwrite, or
wipe checkpoints belonging to other tenants.
The audit posted in #2346 (cc @etairl) listed *Redis key/glob injection
in `RedisSaver` / `ShallowRedisSaver`* among the unfiled findings from
the same security-review pass. This PR confirms the finding and extends
the fix to all key-building sites in both savers.
## Vulnerable sinks
`RedisSaver` (`libs/checkpoint-redis/src/index.ts`):
| Method | Sinks |
|---|---|
| `getTuple` | `keys(\"checkpoint:\${threadId}:\${checkpointNs}:*\")`
plus the direct \`json.get\` key |
| `list` (fallback paths) |
`keys(\"checkpoint:\${threadId}:\${checkpointNs}:*\")`,
`keys(\"checkpoint:*:\${checkpointNs}:*\")` |
| `put` |
`\`checkpoint:\${threadId}:\${checkpointNs}:\${checkpointId}\`` plus the
zset key |
| `putWrites` | per-write key, zset key, checkpoint key |
| `deleteThread` | `keys(\"checkpoint:\${threadId}:*\")`,
`keys(\"writes:\${threadId}:*\")` |
| `loadPendingWrites` |
`keys(\"checkpoint_write:\${threadId}:\${checkpointNs}:\${checkpointId}:*\")`
|
`ShallowRedisSaver` (`libs/checkpoint-redis/src/shallow.ts`) has the
same five public entry points plus the equivalent helper.
## Proof of concept
```ts
import { createClient } from \"redis\";
import { RedisSaver } from \"@langchain/langgraph-checkpoint-redis\";
const client = createClient({ url: process.env.REDIS_URL! });
await client.connect();
const saver = new RedisSaver(client);
// Tenant A and Tenant B persist checkpoints normally.
await saver.put(
{ configurable: { thread_id: \"tenant-a\", checkpoint_ns: \"\" } },
/* checkpoint */ { id: \"cp-a\", v: 4, ts: new Date().toISOString(),
channel_values: {}, channel_versions: {}, versions_seen: {} } as any,
/* metadata */ { source: \"input\", step: 0, parents: {} } as any,
{}
);
await saver.put(
{ configurable: { thread_id: \"tenant-b\", checkpoint_ns: \"\" } },
{ id: \"cp-b\", v: 4, ts: new Date().toISOString(),
channel_values: {}, channel_versions: {}, versions_seen: {} } as any,
{ source: \"input\", step: 0, parents: {} } as any,
{}
);
// Attacker controls only the thread_id of their own request.
// Without the guard, deleteThread expands the KEYS pattern to a glob
// and deletes BOTH tenants' checkpoints.
await saver.deleteThread(\"*\");
// Both \`cp-a\` and \`cp-b\` are gone.
```
The same shape (`\"*\"`, `\"tenant-?\"`, `\"tenant-[ab]\"`, `\"a\\b\"`)
is accepted by every Redis pattern site in the table above.
## Severity
Proposed CVSS 3.1: **High**. The most severe sink is `deleteThread`,
which gives full availability impact across every tenant in the
database, with confidentiality (`getTuple`, `list`) and integrity
(`put`, `putWrites`) impacts on the other paths. Network-reachable,
low-complexity, only the privilege the SDK already grants to a caller.
## Fix
A single `assertSafeKeyComponent` helper exported from `./utils.js`,
applied at every key-building site (27 calls across 2 saver files plus
the helper export). The guard:
* Asserts the value is a non-empty string (the documented empty
`checkpoint_ns` default is opt-in via `{ allowEmpty: true }`).
* Rejects the Redis pattern meta-characters `* ? [ ] \`.
* Rejects the `:` delimiter that would otherwise corrupt the
colon-delimited key structure.
\`\`\`ts
export function assertSafeKeyComponent(
field: string,
value: unknown,
options: { allowEmpty?: boolean } = {}
): asserts value is string {
const { allowEmpty = false } = options;
if (typeof value !== \"string\") { /* precise diagnostic */ throw ... }
if (!allowEmpty && value === \"\") { throw ... }
if (REDIS_KEY_FORBIDDEN.test(value)) { throw ... }
}
\`\`\`
The guard is a TypeScript \`asserts\` predicate so call-sites get type
narrowing for free and the compiler enforces that no later code path
uses an unvalidated identifier.
## Why this design
* Mirrors the maintainers' existing primitive-only pattern
(\`escapeRediSearchTagValue\`) in the same file.
* Single chokepoint: it is impossible for a future call-site to forget
validation.
* No new dependencies, no API changes for valid inputs, no behavior
change for any documented happy path.
* Pairs with PR #2349 (NoSQL injection in MongoDBSaver) so both backends
now share the same defensive posture at the saver boundary.
## Test plan
* [x] 11 new tests under \`describe(\"assertSafeKeyComponent\")\` in
\`libs/checkpoint-redis/src/tests/utils.test.ts\` covering accept and
reject paths for every input shape (normal string, empty with and
without \`allowEmpty\`, every Redis meta-character, colon delimiter,
every wrong type).
* [x] Existing \`escapeRediSearchTagValue\` suite still green
(regression).
* [x] Full suite green (\`pnpm --filter
@langchain/langgraph-checkpoint-redis test\`, 21 of 21).
* [x] Format clean on all 4 changed files (\`oxfmt\`).
* [x] No new dependencies, no public API changes, no behavior change for
valid string identifiers.
## Disclosure
Original finding credited to @etairl (audit posted in #2346 ). This PR
was prepared for coordinated public disclosure since the audit list is
already public. Happy to coordinate timing with a private GHSA if the
maintainers prefer.
---------
Co-authored-by: Nagendhra <nagendhra405@gmail.com >
Co-authored-by: Christian Bromann <git@bromann.dev >
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-05-28 12:58:54 -07:00
github-actions[bot]
7788dceb85
chore: version packages ( #2424 )
...
This PR was opened by the [Changesets
release](https://github.com/changesets/action ) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## @langchain/langgraph-checkpoint-redis@1.0.5
### Patch Changes
- [#2208 ](https://github.com/langchain-ai/langgraphjs/pull/2208 )
[`ebeb145`](https://github.com/langchain-ai/langgraphjs/commit/ebeb1452d27fcca100cd63bdfd4a7f020949412c )
Thanks [@jackjin1997](https://github.com/jackjin1997 )! - Fix
`deleteThread()` using wrong key pattern (`writes:` instead of
`checkpoint_write:`) and add missing cleanup of `write_keys_zset:`
entries.
## @langchain/langgraph-supervisor@1.0.3
### Patch Changes
- [#2317 ](https://github.com/langchain-ai/langgraphjs/pull/2317 )
[`c088c76`](https://github.com/langchain-ai/langgraphjs/commit/c088c7659c18edf26091813ff384f48f5335bef6 )
Thanks [@fish895623](https://github.com/fish895623 )! - feat(supervisor):
widen agents type to accept createAgent graphs
## @langchain/langgraph-sdk@1.9.5
### Patch Changes
- [#2421 ](https://github.com/langchain-ai/langgraphjs/pull/2421 )
[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
fix(stream): align AssembledToolCall typing with pre-v1 expectations
Make `InferToolCalls` resolve to generic `AssembledToolCall` unions,
expose
sync `status`/`error` for reactive bindings, and align type tests across
React, Vue, Svelte, and Angular SDK packages.
## @langchain/angular@1.0.5
### Patch Changes
- [#2421 ](https://github.com/langchain-ai/langgraphjs/pull/2421 )
[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
fix(stream): align AssembledToolCall typing with pre-v1 expectations
Make `InferToolCalls` resolve to generic `AssembledToolCall` unions,
expose
sync `status`/`error` for reactive bindings, and align type tests across
React, Vue, Svelte, and Angular SDK packages.
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/langgraph-sdk@1.9.5
## @langchain/react@1.0.5
### Patch Changes
- [#2421 ](https://github.com/langchain-ai/langgraphjs/pull/2421 )
[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
fix(stream): align AssembledToolCall typing with pre-v1 expectations
Make `InferToolCalls` resolve to generic `AssembledToolCall` unions,
expose
sync `status`/`error` for reactive bindings, and align type tests across
React, Vue, Svelte, and Angular SDK packages.
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/langgraph-sdk@1.9.5
## @langchain/svelte@1.0.5
### Patch Changes
- [#2421 ](https://github.com/langchain-ai/langgraphjs/pull/2421 )
[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
fix(stream): align AssembledToolCall typing with pre-v1 expectations
Make `InferToolCalls` resolve to generic `AssembledToolCall` unions,
expose
sync `status`/`error` for reactive bindings, and align type tests across
React, Vue, Svelte, and Angular SDK packages.
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/langgraph-sdk@1.9.5
## @langchain/vue@1.0.5
### Patch Changes
- [#2421 ](https://github.com/langchain-ai/langgraphjs/pull/2421 )
[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )
Thanks [@christian-bromann](https://github.com/christian-bromann )! -
fix(stream): align AssembledToolCall typing with pre-v1 expectations
Make `InferToolCalls` resolve to generic `AssembledToolCall` unions,
expose
sync `status`/`error` for reactive bindings, and align type tests across
React, Vue, Svelte, and Angular SDK packages.
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/langgraph-sdk@1.9.5
## @example/ai-elements@0.1.20
### Patch Changes
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/react@1.0.5
## @examples/assistant-ui-claude@0.1.20
### Patch Changes
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/react@1.0.5
## @examples/ui-angular@0.0.30
### Patch Changes
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/langgraph-sdk@1.9.5
- @langchain/angular@1.0.5
## @examples/ui-multimodal@0.0.6
### Patch Changes
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/react@1.0.5
## @examples/ui-react@0.0.6
### Patch Changes
- Updated dependencies
\[[`3529e38`](https://github.com/langchain-ai/langgraphjs/commit/3529e3831a488134e7dfaefa4ed7fb1140cf8bb6 )]:
- @langchain/langgraph-sdk@1.9.5
- @langchain/react@1.0.5
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-22 07:16:17 -07:00
Jackjin
ebeb1452d2
fix(langgraph-checkpoint-redis): fix deleteThread using wrong key pattern for writes ( #2208 )
...
## Summary
Fixes #2207
- Fix `deleteThread()` using incorrect `writes:` prefix instead of
`checkpoint_write:` for write key deletion
- Add missing cleanup of `write_keys_zset:` entries, matching the
correct implementation in `ShallowRedisSaver`
The bug was found by comparing `RedisSaver.deleteThread()` with
`ShallowRedisSaver.deleteThread()` in `shallow.ts`, which correctly uses
`checkpoint_write:` prefix and also cleans up zset keys.
## AI Disclosure
This bug was identified through code review with AI assistance. The fix
aligns the standard `RedisSaver` implementation with the existing
correct `ShallowRedisSaver` implementation.
---------
Co-authored-by: Christian Bromann <git@bromann.dev >
2026-05-22 06:57:22 -07:00
Christian Bromann
085a07f569
feat(core): event based streaming ( #2314 )
...
All stream v2 changes consolidated.
---------
Co-authored-by: Hunter Lovell <hunter@hntrl.io >
2026-05-05 00:13:12 -07:00
Hunter Lovell
9102d526c8
fix(langgraph): propagate tracer metadata defaults from configurable ( #2315 )
...
## Summary
This updates Pregel callback manager initialization to pass
`tracerInheritableMetadata` defaults derived from `config.configurable`,
and narrows `ensureLangGraphConfig` metadata mirroring to the
allowlisted LangGraph identifiers used in stream/runtime metadata.
## Changes
### `@langchain/langgraph` (`libs/langgraph-core`)
- Updated Pregel callback manager setup to configure core callbacks with
`tracerInheritableMetadata` based on configurable primitive values,
excluding internal and secret-like keys.
- Hoisted tracing default logic into `_getTracingMetadataDefaults` and
`_excludeAsMetadata` for parity with the Python implementation shape.
- Restricted `ensureLangGraphConfig` configurable-to-metadata
propagation to the identifier allowlist:
- `thread_id`
- `checkpoint_id`
- `checkpoint_ns`
- `task_id`
- `run_id`
- `assistant_id`
- `graph_id`
- Updated config tests to assert the narrowed metadata propagation
behavior.
2026-04-15 18:48:41 -07:00
Christian Bromann
d88f29ba25
chore(repo): migrate linting and formatting from ESLint/Prettier to oxlint/oxfmt ( #2256 )
...
Co-authored-by: Cursor Agent <cursoragent@cursor.com >
Co-authored-by: Christian Bromann <christian-bromann@users.noreply.github.com >
Co-authored-by: Hunter Lovell <40191806+hntrl@users.noreply.github.com >
2026-03-30 18:08:00 -07:00
github-actions[bot]
a1e2abff1e
chore: version packages ( #2174 )
...
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hunter Lovell <hunter@hntrl.io >
2026-03-17 18:10:42 +00:00
Christian Bromann
a8f1b9d26b
fix(checkpoint-redis): fix dependency ( #2181 )
2026-03-12 17:08:19 -07:00
github-actions[bot]
dc37d3cd62
chore: version packages ( #2025 )
...
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hunter Lovell <hunter@hntrl.io >
2026-03-06 14:11:51 -08:00
pawel-twardziak
c35c274a5d
fix(checkpoint-redis): detect existing writes in put to preserve has_writes flag ( #2026 )
...
Co-authored-by: Christian Bromann <git@bromann.dev >
2026-03-05 13:38:45 -08:00
John Kennedy
194e5bf1e5
fix: use comprehensive RediSearch tag escaping ( #2012 )
...
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 00:19:35 +00:00
John Kennedy
9c0c92e121
fix: bump testcontainers to ^11 in checkpoint-redis to resolve CVE-2026-22036 ( #1982 )
...
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-02-19 19:44:35 +00:00
github-actions[bot]
289cc95bea
chore: version packages ( #1941 )
...
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hunter Lovell <hunter@hntrl.io >
2026-02-04 18:07:19 -08:00
Hunter Lovell
814c76dc39
fix(checkpoint): improve sanitization in Redis and MongoDB filters ( #1943 )
2026-02-04 16:14:50 -08:00
David Duong
6d5cdcbb10
fix(chore): replace turbo:command with plain turbo ( #1869 )
2026-01-09 19:16:10 +00:00
David Duong
e7aeffeb72
chore: replace yarn with pnpm ( #1862 )
...
Co-authored-by: Christian Bromann <git@bromann.dev >
2026-01-09 19:52:29 +01:00
Josh Rogers
f602df6593
fix(langgraph): add resumable stream support to remote graph ( #1827 )
...
Co-authored-by: Hunter Lovell <40191806+hntrl@users.noreply.github.com >
2025-12-17 16:20:14 -05:00
Christian Bromann
52dc36b425
fix(*): set proper url prefix for package reference ( #1811 )
2025-12-07 12:13:53 -08:00
github-actions[bot]
3e81549d0b
Version Packages ( #1801 )
...
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-02 02:50:39 +01:00
Christian Bromann
9440d080e6
fix(@langchain/langgraph-checkpoint-redis): deserialize checkpointed state ( #1768 )
...
Co-authored-by: David Duong <david@duong.cz >
2025-12-02 00:35:38 +00:00
David Duong
fdd5878e89
chore: update dependencies ( #1774 )
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 14:43:13 +00:00
github-actions[bot]
d4b6d9ca98
Version Packages ( #1735 )
...
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hunter Lovell <hunter@hntrl.io >
2025-10-17 16:59:01 -07:00
Hunter Lovell
1e1ecbbcf8
feat: merge v1 ( #1733 )
...
Co-authored-by: Tat Dat Duong <david@duong.cz >
Co-authored-by: Christian Bromann <git@bromann.dev >
Co-authored-by: Nuno Campos <nuno@langchain.dev >
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-17 16:34:43 -07:00
github-actions[bot]
c90a7fb74d
Version Packages ( #1714 )
...
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-30 13:47:08 +02:00
Baptiste Jamin
926db1efe9
fix(langgraph-checkpoint-redis): allow alpha version of 1.0.0 ( #1701 )
...
Co-authored-by: Baptiste Jamin <baptiste@crisp.chat >
Co-authored-by: David Duong <david@duong.cz >
2025-09-30 11:28:03 +00:00
David Duong
03ae1089ea
chore: remove release-it, fix dependabot for tmp ( #1638 )
2025-09-10 19:08:13 +00:00
Brian Sam-Bodden
2c6cc0ac9e
feat(checkpoint-redis): add Redis-based checkpoint and store implemen… ( #1544 )
...
Co-authored-by: Tat Dat Duong <david@duong.cz >
2025-09-04 19:08:10 +02:00