langgraph icon indicating copy to clipboard operation
langgraph copied to clipboard

time travel works unexpected when using return Command

Open vapour1024 opened this issue 2 months ago • 3 comments

Checked other resources

  • [x] This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
  • [x] I added a clear and detailed title that summarizes the issue.
  • [x] I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
  • [x] I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.

Example Code

import sys
import uuid

from langgraph.types import Command
from typing_extensions import TypedDict, NotRequired
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver


class State(TypedDict):
    topic: NotRequired[str]
    joke: NotRequired[str]
    output: NotRequired[str]


def generate_topic(state: State):
    return Command(
        update={"topic": "milk"},
        goto="write_joke"
    )
    # return {"topic": "milk"}


def write_joke(state: State):
    print(f"write_joke state.get topic is {state.get("topic")}")
    if state.get("topic") == "chickens":
        return Command(
            goto=END
        )
    else:
        return Command(
            update={"joke": f"Why did the chicken join a {state['topic']}"},
            goto="play_joke"
        )
    # return {"joke": f"Why did the chicken join a {state['topic']}"}


def play_joke(state: State):
    return Command(
        update={"output": f"play the joke about {state["topic"]}"},
        goto=END
    )
    # return {"output": f"play the joke about {state["topic"]}"}


# Build workflow
workflow = StateGraph(State)

# Add nodes
workflow.add_node("generate_topic", generate_topic)
workflow.add_node("write_joke", write_joke)
workflow.add_node("play_joke", play_joke)

# Add edges to connect nodes
workflow.add_edge(START, "generate_topic")
# workflow.add_edge("generate_topic", "write_joke")
# workflow.add_edge("write_joke", "play_joke")
# workflow.add_edge("play_joke", END)

# Compile
checkpointer = InMemorySaver()
graph = workflow.compile(checkpointer=checkpointer)
config = {
    "configurable": {
        "thread_id": uuid.uuid4(),
    }
}
state = graph.invoke({}, config)

full_history = list(graph.get_state_history(config))
print("full_history:")
for i, step in enumerate(full_history):
    print(f"step {i}:")
    print(f"checkpoint_id: {step.config['configurable'].get('checkpoint_id')}")
    print(f"  time: {step.created_at}")
    print(f"  values: {step.values}")
    print(f"next: {step.next}")
    print("---")

selected_state = full_history[2]
print("selected_state:")
print(selected_state.next)
print(selected_state.values)

new_config = graph.update_state(
    selected_state.config,
    values={"topic": "chickens"},
)
print(new_config)

graph.invoke(None, new_config)

full_history = list(graph.get_state_history(config))
print("full_history:")
for i, step in enumerate(full_history):
    print(f"step {i}:")
    print(f"checkpoint_id: {step.config['configurable'].get('checkpoint_id')}")
    print(f"time: {step.created_at}")
    print(f"values: {step.values}")
    print(f"next: {step.next}")
    print("---")

Error Message and Stack Trace (if applicable)

write_joke state.get topic is milk
full_history:
step 0:
checkpoint_id: 1f0afb2b-0c93-66a1-8003-4e60091b7341
  time: 2025-10-23T01:50:45.350150+00:00
  values: {'topic': 'milk', 'joke': 'Why did the chicken join a milk', 'output': 'play the joke about milk'}
next: ()
---
step 1:
checkpoint_id: 1f0afb2b-0c91-6e12-8002-babaca22cfbd
  time: 2025-10-23T01:50:45.349520+00:00
  values: {'topic': 'milk', 'joke': 'Why did the chicken join a milk'}
next: ('play_joke',)
---
step 2:
checkpoint_id: 1f0afb2b-0c8f-614c-8001-715a8642b0da
  time: 2025-10-23T01:50:45.348376+00:00
  values: {'topic': 'milk'}
next: ('write_joke',)
---
step 3:
checkpoint_id: 1f0afb2b-0c8d-6602-8000-6b316f8d4526
  time: 2025-10-23T01:50:45.347676+00:00
  values: {}
next: ('generate_topic',)
---
step 4:
checkpoint_id: 1f0afb2b-0c8a-688b-bfff-2a840fb00e4a
  time: 2025-10-23T01:50:45.346517+00:00
  values: {}
next: ('__start__',)
---
selected_state:
('write_joke',)
{'topic': 'milk'}
{'configurable': {'thread_id': 'd5487fd6-7b33-4c0c-ae29-ea6f0fe3f204', 'checkpoint_ns': '', 'checkpoint_id': '1f0afb2b-0c97-6e47-8002-1c22201756cc'}}
full_history:
step 0:
checkpoint_id: 1f0afb2b-0c97-6e47-8002-1c22201756cc
time: 2025-10-23T01:50:45.351982+00:00
values: {'topic': 'chickens', 'joke': 'Why did the chicken join a milk'}
next: ()
---
step 1:
checkpoint_id: 1f0afb2b-0c93-66a1-8003-4e60091b7341
time: 2025-10-23T01:50:45.350150+00:00
values: {'topic': 'milk', 'joke': 'Why did the chicken join a milk', 'output': 'play the joke about milk'}
next: ()
---
step 2:
checkpoint_id: 1f0afb2b-0c91-6e12-8002-babaca22cfbd
time: 2025-10-23T01:50:45.349520+00:00
values: {'topic': 'milk', 'joke': 'Why did the chicken join a milk'}
next: ('play_joke',)
---
step 3:
checkpoint_id: 1f0afb2b-0c8f-614c-8001-715a8642b0da
time: 2025-10-23T01:50:45.348376+00:00
values: {'topic': 'milk'}
next: ('write_joke',)
---
step 4:
checkpoint_id: 1f0afb2b-0c8d-6602-8000-6b316f8d4526
time: 2025-10-23T01:50:45.347676+00:00
values: {}
next: ('generate_topic',)
---
step 5:
checkpoint_id: 1f0afb2b-0c8a-688b-bfff-2a840fb00e4a
time: 2025-10-23T01:50:45.346517+00:00
values: {}
next: ('__start__',)
---

Description

  1. rungraph.update_state and get a new_config
  2. run graph.invoke(None, new_config) graph doesn't run node write_joke and doesn't goto END is this an expected behavior when using return Command for node switch instead of workflow.add_edge?

System Info

System Information

OS: Linux OS Version: #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 Python Version: 3.12.10 (main, Apr 9 2025, 04:03:51) [Clang 20.1.0 ]

Package Information

langchain_core: 0.3.74 langchain: 0.3.26 langchain_community: 0.3.27 langsmith: 0.4.6 langchain_chroma: 0.2.4 langchain_deepseek: 0.1.4 langchain_openai: 0.3.28 langchain_retrive_test: Installed. No version info available. langchain_tavily: 0.2.10 langchain_test: Installed. No version info available. langchain_text_splitters: 0.3.8 langgraph_sdk: 0.2.9

Optional packages not installed

langserve

Other Dependencies

aiohttp: 3.12.14 aiohttp<4.0.0,>=3.8.3: Installed. No version info available. async-timeout<5.0.0,>=4.0.0;: Installed. No version info available. chromadb>=1.0.9: Installed. No version info available. dataclasses-json<0.7,>=0.5.7: Installed. No version info available. httpx: 0.28.1 httpx-sse<1.0.0,>=0.4.0: Installed. No version info available. httpx>=0.25.2: Installed. No version info available. jsonpatch<2.0,>=1.33: Installed. No version info available. langchain-anthropic;: Installed. No version info available. langchain-aws;: Installed. No version info available. langchain-azure-ai;: Installed. No version info available. langchain-cohere;: Installed. No version info available. langchain-community;: Installed. No version info available. langchain-core<1.0.0,>=0.3.51: Installed. No version info available. langchain-core<1.0.0,>=0.3.66: Installed. No version info available. langchain-core<1.0.0,>=0.3.68: Installed. No version info available. langchain-core<1.0.0,>=0.3.70: Installed. No version info available. langchain-core>=0.3.60: Installed. No version info available. langchain-deepseek;: Installed. No version info available. langchain-fireworks;: Installed. No version info available. langchain-google-genai;: Installed. No version info available. langchain-google-vertexai;: Installed. No version info available. langchain-groq;: Installed. No version info available. langchain-huggingface;: Installed. No version info available. langchain-mistralai;: Installed. No version info available. langchain-ollama;: Installed. No version info available. langchain-openai;: Installed. No version info available. langchain-openai<1.0.0,>=0.3.28: Installed. No version info available. langchain-perplexity;: Installed. No version info available. langchain-text-splitters<1.0.0,>=0.3.8: Installed. No version info available. langchain-together;: Installed. No version info available. langchain-xai;: Installed. No version info available. langchain<1.0.0,>=0.3.26: Installed. No version info available. langsmith-pyo3: Installed. No version info available. langsmith>=0.1.125: Installed. No version info available. langsmith>=0.1.17: Installed. No version info available. langsmith>=0.3.45: Installed. No version info available. numpy>=1.26.0;: Installed. No version info available. numpy>=1.26.2;: Installed. No version info available. numpy>=2.1.0;: Installed. No version info available. openai-agents: Installed. No version info available. openai<2.0.0,>=1.86.0: Installed. No version info available. opentelemetry-api: 1.35.0 opentelemetry-exporter-otlp-proto-http: Installed. No version info available. opentelemetry-sdk: 1.35.0 orjson: 3.11.0 orjson>=3.10.1: Installed. No version info available. packaging: 25.0 packaging>=23.2: Installed. No version info available. pydantic: 2.11.7 pydantic-settings<3.0.0,>=2.4.0: Installed. No version info available. pydantic<3.0.0,>=2.7.4: Installed. No version info available. pydantic>=2.7.4: Installed. No version info available. pytest: Installed. No version info available. PyYAML>=5.3: Installed. No version info available. requests: 2.32.4 requests-toolbelt: 1.0.0 requests<3,>=2: Installed. No version info available. rich: 14.0.0 SQLAlchemy<3,>=1.4: Installed. No version info available. tenacity!=8.4.0,<10,>=8.1.0: Installed. No version info available. tenacity!=8.4.0,<10.0.0,>=8.1.0: Installed. No version info available. tiktoken<1,>=0.7: Installed. No version info available. typing-extensions>=4.7: Installed. No version info available. zstandard: 0.23.0

vapour1024 avatar Oct 23 '25 01:10 vapour1024

Confirmed can repro. State update doesn't seem to work when edges are Command goto

casparb avatar Nov 07 '25 18:11 casparb

Is there a plan which supports time travel for Command goto?

vapour1024 avatar Nov 13 '25 00:11 vapour1024

I'll look into this further soon and get back to you @vapour1024 !

casparb avatar Nov 13 '25 19:11 casparb