[GH-ISSUE #2847] [langgraph]: checkpoint_ns in config is silently reset to "" when manually invoking a compiled graph, breaking checkpoint isolation #2685

Open
opened 2026-06-05 17:26:17 -04:00 by yindo · 0 comments
Owner

Originally created by @Aryanskill on GitHub (Feb 27, 2026).
Original GitHub issue: https://github.com/langchain-ai/docs/issues/2847

Type of issue

issue / bug

Language

Python

Description

Description:

When manually calling graph.invoke(state, config) from within a node/adapter function (a valid pattern for complex state transformation between graphs), the checkpoint_ns value provided in config is silently cleared to "". This causes checkpoint namespace collisions when using PostgresSaver with multiple graphs sharing a checkpointer.

Expected Behavior:
User-provided checkpoint_ns in config should be preserved, or at minimum a warning should be logged when it's being overwritten.

Actual Behavior and root cause:
The checkpoint_ns is reset to "" because the invoked graph doesn't have __pregel_task_id in its config, so is_nested=False, triggering below code
In loop.py (v0.4.8), the PregelLoop.init :

`# Line 248
self.is_nested = CONFIG_KEY_TASK_ID in self.config.get(CONF, {})

Lines 279-283

if not self.is_nested and config[CONF].get(CONFIG_KEY_CHECKPOINT_NS):
self.config = patch_configurable(
self.config,
{CONFIG_KEY_CHECKPOINT_NS: "", CONFIG_KEY_CHECKPOINT_ID: None},
)`

The is_nested flag is determined solely by presence of __pregel_task_id in config. This key is only set automatically when using "graph-as-node" composition. When using the "invoke from adapter" pattern, this key is absent → is_nested=False → checkpoint_ns gets wiped.

Workaround
Manually set __pregel_task_id in config to trick the nested detection:

config = {"configurable": { "thread_id": state["thread_id"], "checkpoint_ns": "GRAPH_B", "__pregel_task_id": "any_string" # <-- Preserves checkpoint_ns }}

Originally created by @Aryanskill on GitHub (Feb 27, 2026). Original GitHub issue: https://github.com/langchain-ai/docs/issues/2847 ### Type of issue issue / bug ### Language Python ### Description **Description:** When manually calling graph.invoke(state, config) from within a node/adapter function (a valid pattern for complex state transformation between graphs), the checkpoint_ns value provided in config is silently cleared to "". This causes checkpoint namespace collisions when using PostgresSaver with multiple graphs sharing a checkpointer. **Expected Behavior:** User-provided checkpoint_ns in config should be preserved, or at minimum a warning should be logged when it's being overwritten. **Actual Behavior and root cause:** The checkpoint_ns is reset to "" because the invoked graph doesn't have __pregel_task_id in its config, so is_nested=False, triggering below code In loop.py (v0.4.8), the PregelLoop.__init__ : `# Line 248 self.is_nested = CONFIG_KEY_TASK_ID in self.config.get(CONF, {}) # Lines 279-283 if not self.is_nested and config[CONF].get(CONFIG_KEY_CHECKPOINT_NS): self.config = patch_configurable( self.config, {CONFIG_KEY_CHECKPOINT_NS: "", CONFIG_KEY_CHECKPOINT_ID: None}, )` The is_nested flag is determined solely by presence of __pregel_task_id in config. This key is only set automatically when using "graph-as-node" composition. When using the "invoke from adapter" pattern, this key is absent → is_nested=False → checkpoint_ns gets wiped. **Workaround** Manually set __pregel_task_id in config to trick the nested detection: `config = {"configurable": { "thread_id": state["thread_id"], "checkpoint_ns": "GRAPH_B", "__pregel_task_id": "any_string" # <-- Preserves checkpoint_ns }}`
yindo added the langgraphexternal labels 2026-06-05 17:26:17 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/docs#2685