updateState broken for functional API graphs #255

Closed
opened 2026-02-15 18:15:06 -05:00 by yindo · 2 comments
Owner

Originally created by @keikumata on GitHub (May 8, 2025).

Title

InvalidUpdateError: No writers found for node "agent-supervisor" when calling updateState

Context

I’m building a LangGraph‑powered agent using the entrypoint API, and everything works up through calling getState(). However, when I try to push updates back with updateState(), I get the following runtime error:

InvalidUpdateError: No writers found for node "agent-supervisor"
    at Pregel.updateState (…/node_modules/@langchain/langgraph/src/pregel/index.ts:1172:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at EventTarget.abortSignal.onabort (…/ReActAgentGraph.ts:523:17) {
  lc_error_code: undefined
}

What I’m doing

  • I register an entrypoint called “agent-supervisor” that receives the current message array, does some processing, and returns a final state.

  • The agentSupervisor is created like this:

    const agentSupervisor = entrypoint(
      {
        name: 'agent-supervisor',
        checkpointer: context.checkpointer,
      },
      async (messages: BaseMessage[]) => {
        // process messages…
        return entrypoint.final({
          value: currentMessages,
          save: currentMessages,
        });
      }
    );
    
  • Elsewhere, in an abort handler, I do:

    abortSignal.onabort = async () => {
      try {
        // 1) Fetch the current messages
        const state = await agentSupervisor.getState(langGraphConfig);
        const messages = state.values;
    
        // 2) Mutate the messages array as needed...
    
        // 3) Push the updated messages back into LangGraph
        await agentSupervisor.updateState(langGraphConfig, { messages });
      } catch (error) {
        console.error(error);
      }
    };
    

Expected behavior

Calling updateState() with a modified messages array should merge or overwrite the node’s state in the graph.

Actual behavior

updateState() throws InvalidUpdateError: No writers found for node "agent-supervisor".

Any guidance or pointers to relevant LangGraph internals would be greatly appreciated!

Originally created by @keikumata on GitHub (May 8, 2025). # Title `InvalidUpdateError: No writers found for node "agent-supervisor" when calling updateState` # Context I’m building a LangGraph‑powered agent using the entrypoint API, and everything works up through calling `getState()`. However, when I try to push updates back with `updateState()`, I get the following runtime error: ``` InvalidUpdateError: No writers found for node "agent-supervisor" at Pregel.updateState (…/node_modules/@langchain/langgraph/src/pregel/index.ts:1172:12) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at EventTarget.abortSignal.onabort (…/ReActAgentGraph.ts:523:17) { lc_error_code: undefined } ``` # What I’m doing * I register an entrypoint called “agent-supervisor” that receives the current message array, does some processing, and returns a final state. * The `agentSupervisor` is created like this: ```ts const agentSupervisor = entrypoint( { name: 'agent-supervisor', checkpointer: context.checkpointer, }, async (messages: BaseMessage[]) => { // process messages… return entrypoint.final({ value: currentMessages, save: currentMessages, }); } ); ``` * Elsewhere, in an abort handler, I do: ```ts abortSignal.onabort = async () => { try { // 1) Fetch the current messages const state = await agentSupervisor.getState(langGraphConfig); const messages = state.values; // 2) Mutate the messages array as needed... // 3) Push the updated messages back into LangGraph await agentSupervisor.updateState(langGraphConfig, { messages }); } catch (error) { console.error(error); } }; ``` # Expected behavior Calling `updateState()` with a modified `messages` array should merge or overwrite the node’s state in the graph. # Actual behavior `updateState()` throws `InvalidUpdateError: No writers found for node "agent-supervisor"`. Any guidance or pointers to relevant LangGraph internals would be greatly appreciated!
yindo closed this issue 2026-02-15 18:15:06 -05:00
Author
Owner

@benjamincburns commented on GitHub (May 9, 2025):

Reopening this, as a result of needing to rollback #1163 in #1168

@benjamincburns commented on GitHub (May 9, 2025): Reopening this, as a result of needing to rollback #1163 in #1168
Author
Owner

@dqbd commented on GitHub (Jun 26, 2025):

This should be already fixed! If you need to obtain the previously saved values, use getPreviousState() to retrieve it.

const graph = entrypoint(
  { name: "random", checkpointer },
  async (human: BaseMessage) => {
    const messages = getPreviousState<BaseMessage[]>() ?? [];
    const ai = new AIMessage(`ai: ${human.text}`);
    return [...messages, human, ai];
  }
);

const config = { configurable: { thread_id: "1" } };

expect(await graph.invoke(new HumanMessage("hello"), config)).toEqual([
  new HumanMessage("hello"),
  new AIMessage("ai: hello"),
]);

expect(await graph.getState(config)).toMatchObject({
  values: [new HumanMessage("hello"), new AIMessage("ai: hello")],
});

// update state with new messages
await graph.updateState(config, [
  new HumanMessage("ahoj"),
  new AIMessage("ai: ahoj"),
]);

expect(
  await graph.invoke(new HumanMessage("jak se máš?"), config)
).toEqual([
  new HumanMessage("ahoj"),
  new AIMessage("ai: ahoj"),
  new HumanMessage("jak se máš?"),
  new AIMessage("ai: jak se máš?"),
]);
@dqbd commented on GitHub (Jun 26, 2025): This should be already fixed! If you need to obtain the previously saved values, use `getPreviousState()` to retrieve it. ```ts const graph = entrypoint( { name: "random", checkpointer }, async (human: BaseMessage) => { const messages = getPreviousState<BaseMessage[]>() ?? []; const ai = new AIMessage(`ai: ${human.text}`); return [...messages, human, ai]; } ); const config = { configurable: { thread_id: "1" } }; expect(await graph.invoke(new HumanMessage("hello"), config)).toEqual([ new HumanMessage("hello"), new AIMessage("ai: hello"), ]); expect(await graph.getState(config)).toMatchObject({ values: [new HumanMessage("hello"), new AIMessage("ai: hello")], }); // update state with new messages await graph.updateState(config, [ new HumanMessage("ahoj"), new AIMessage("ai: ahoj"), ]); expect( await graph.invoke(new HumanMessage("jak se máš?"), config) ).toEqual([ new HumanMessage("ahoj"), new AIMessage("ai: ahoj"), new HumanMessage("jak se máš?"), new AIMessage("ai: jak se máš?"), ]); ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraphjs#255