Missing State in ConditionalEdges when Using Input, Output, and State Schema Splitting #91

Closed
opened 2026-02-15 17:15:38 -05:00 by yindo · 1 comment
Owner

Originally created by @shaharov on GitHub (Sep 24, 2024).

Originally assigned to: @jacoblee93 on GitHub.

langgraph version 0.2.8

I'm currently working on defining a graph with separate schemas for input, output, and additional state using StateGraph. Below is a simplified flow illustrating the issue:

START -> FirstNode -> [dummy-conditional-edge] -> LastNode -> END

The graph contains InputDefinition, OutputDefinition, and an additional state field in InnerNodesDefinition, all merged into GraphDefinition.

Expected console output:

import { END, StateGraph, Annotation, START } from "@langchain/langgraph";

export const InputDefinition = Annotation.Root({
	input: Annotation<string>,
});
export const OutputDefinition = Annotation.Root({
	output: Annotation<string>,
});

export const InnerNodesDefinition = Annotation.Root({
	innerString: Annotation<string>,
});
export const GraphDefinition = Annotation.Root({
	...InputDefinition.spec,
	...OutputDefinition.spec,
	...InnerNodesDefinition.spec,
});

const FirstNode = async (state: typeof GraphDefinition.State) => {
	console.log("FirstNode: ", state);
	return {
		innerString: "InnerNodesString",
	};
};
const route = async (state: typeof GraphDefinition.State) => {
	console.log("Route: ", state);
	return "LastNode";
};
const LastNode = async (state: typeof GraphDefinition.State) => {
	console.log("LastNode:", state);
	return {
		output: "bye",
	};
};
async function test() {
	const builder = new StateGraph({ input: InputDefinition, output: OutputDefinition, stateSchema: GraphDefinition })
		.addNode("FirstNode", FirstNode)
		.addNode("LastNode", LastNode)
		.addEdge(START, "FirstNode")
		.addConditionalEdges("FirstNode", route);
		.addEdge("LastNode", END)

	const graph = builder.compile();

	const res = await graph.invoke({ input: "InputString" });
	console.log("Response", res);
}

test();

I expect the console output to look like this:

FirstNode:  { input: 'InputString', output: null, innerString: null }
Route:  { input: 'InputString', innerString: 'InnerNodesString' }
LastNode: { input: 'InputString', output: null, innerString: 'InnerNodesString' }
Response { output: 'bye' }

However, the actual output is:

FirstNode:  { input: 'InputString', output: null, innerString: null }
Route:  {}
LastNode: { input: 'InputString', output: null, innerString: 'InnerNodesString' }
Response { output: 'bye' }

As shown above, the state in the route function is empty.

Interestingly, when I change the line:

const builder = new StateGraph({ input: InputDefinition, output: OutputDefinition, stateSchema: GraphDefinition });

to:

const builder = new StateGraph(GraphDefinition);

I get the expected output in the route node.


It seems like the state isn't passed correctly to the route function when splitting input, output, and state schemas. Could this be a bug, or am I missing something in the schema definition? Any insights would be appreciated!

Originally created by @shaharov on GitHub (Sep 24, 2024). Originally assigned to: @jacoblee93 on GitHub. _langgraph version 0.2.8_ I'm currently working on defining a graph with separate schemas for input, output, and additional state using `StateGraph`. Below is a simplified flow illustrating the issue: ``` START -> FirstNode -> [dummy-conditional-edge] -> LastNode -> END ``` The graph contains `InputDefinition`, `OutputDefinition`, and an additional state field in `InnerNodesDefinition`, all merged into `GraphDefinition`. Expected console output: ```typescript import { END, StateGraph, Annotation, START } from "@langchain/langgraph"; export const InputDefinition = Annotation.Root({ input: Annotation<string>, }); export const OutputDefinition = Annotation.Root({ output: Annotation<string>, }); export const InnerNodesDefinition = Annotation.Root({ innerString: Annotation<string>, }); export const GraphDefinition = Annotation.Root({ ...InputDefinition.spec, ...OutputDefinition.spec, ...InnerNodesDefinition.spec, }); const FirstNode = async (state: typeof GraphDefinition.State) => { console.log("FirstNode: ", state); return { innerString: "InnerNodesString", }; }; const route = async (state: typeof GraphDefinition.State) => { console.log("Route: ", state); return "LastNode"; }; const LastNode = async (state: typeof GraphDefinition.State) => { console.log("LastNode:", state); return { output: "bye", }; }; async function test() { const builder = new StateGraph({ input: InputDefinition, output: OutputDefinition, stateSchema: GraphDefinition }) .addNode("FirstNode", FirstNode) .addNode("LastNode", LastNode) .addEdge(START, "FirstNode") .addConditionalEdges("FirstNode", route); .addEdge("LastNode", END) const graph = builder.compile(); const res = await graph.invoke({ input: "InputString" }); console.log("Response", res); } test(); ``` I expect the console output to look like this: ``` FirstNode: { input: 'InputString', output: null, innerString: null } Route: { input: 'InputString', innerString: 'InnerNodesString' } LastNode: { input: 'InputString', output: null, innerString: 'InnerNodesString' } Response { output: 'bye' } ``` However, the actual output is: ``` FirstNode: { input: 'InputString', output: null, innerString: null } Route: {} LastNode: { input: 'InputString', output: null, innerString: 'InnerNodesString' } Response { output: 'bye' } ``` As shown above, the state in the `route` function is empty. Interestingly, when I change the line: ```typescript const builder = new StateGraph({ input: InputDefinition, output: OutputDefinition, stateSchema: GraphDefinition }); ``` to: ```typescript const builder = new StateGraph(GraphDefinition); ``` I get the expected output in the `route` node. --- It seems like the state isn't passed correctly to the route function when splitting input, output, and state schemas. Could this be a bug, or am I missing something in the schema definition? Any insights would be appreciated!
yindo closed this issue 2026-02-15 17:15:38 -05:00
Author
Owner

@jacoblee93 commented on GitHub (Sep 28, 2024):

This appears to be a bug - will have a look!

@jacoblee93 commented on GitHub (Sep 28, 2024): This appears to be a bug - will have a look!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraphjs#91