The LangGraph Agent Spec runtime does not enforce the schema declared on an EndNode when returning the final flow output.
A minimal flow was created with:
- A permissive
StartNode schema, allowing the test payload to enter the flow.
- A strict
EndNode schema requiring:
name
profile
profile.score
profile.active
profile.tags
- A direct
DataFlowEdge from the StartNode payload to the EndNode.
The serialized Agent Spec correctly contains the strict schema on the EndNode, including:
{
"required": ["name", "profile"],
"properties": {
"profile": {
"required": ["score", "active", "tags"]
}
}
}
Valid case
The following payload conforms to the EndNode schema:
{
"name": "Ada",
"profile": {
"score": 0.98,
"active": true,
"tags": ["verified", "structured"]
}
}
Both LangGraph and Wayflow successfully return this payload.
Invalid case
The following payload is intentionally missing the required nested field profile.active:
{
"name": "Ada",
"profile": {
"score": 0.98,
"tags": ["verified", "structured"]
}
}
The permissive StartNode allows this value to enter the flow. The value then reaches an EndNode whose declared schema requires profile.active.
Expected Behavior
The runtime should reject the value at the EndNode boundary because it does not conform to the EndNode's declared output schema.
The invalid value should not be returned as a successful flow output.
Actual Behavior
LangGraph
LangGraph accepts the invalid value and successfully completes the flow:
AgentSpecFinishedExecutionStatus(
outputs={
"payload": {
"name": "Ada",
"profile": {
"score": 0.98,
"tags": ["verified", "structured"]
}
}
},
agent_messages=[]
)
No validation error is raised even though the returned value violates the EndNode schema.
Wayflow
Wayflow rejects the same value with a TypeError because it does not satisfy the expected ObjectProperty.
This is the expected behavior.
Runtime Comparison
| Runtime |
Valid payload |
Missing profile.active |
| Wayflow |
Accepted |
Rejected |
| LangGraph |
Accepted |
Accepted |
| Expected |
Accepted |
Rejected |
Impact
An Agent Spec flow executed by the LangGraph runtime can successfully return values that violate the schema explicitly declared by its EndNode.
This makes the EndNode output contract unenforced and produces different behavior for the same Agent Spec across runtimes.
The LangGraph Agent Spec runtime does not enforce the schema declared on an
EndNodewhen returning the final flow output.A minimal flow was created with:
StartNodeschema, allowing the test payload to enter the flow.EndNodeschema requiring:nameprofileprofile.scoreprofile.activeprofile.tagsDataFlowEdgefrom theStartNodepayload to theEndNode.The serialized Agent Spec correctly contains the strict schema on the
EndNode, including:{ "required": ["name", "profile"], "properties": { "profile": { "required": ["score", "active", "tags"] } } }Valid case
The following payload conforms to the
EndNodeschema:{ "name": "Ada", "profile": { "score": 0.98, "active": true, "tags": ["verified", "structured"] } }Both LangGraph and Wayflow successfully return this payload.
Invalid case
The following payload is intentionally missing the required nested field
profile.active:{ "name": "Ada", "profile": { "score": 0.98, "tags": ["verified", "structured"] } }The permissive
StartNodeallows this value to enter the flow. The value then reaches anEndNodewhose declared schema requiresprofile.active.Expected Behavior
The runtime should reject the value at the
EndNodeboundary because it does not conform to theEndNode's declared output schema.The invalid value should not be returned as a successful flow output.
Actual Behavior
LangGraph
LangGraph accepts the invalid value and successfully completes the flow:
No validation error is raised even though the returned value violates the
EndNodeschema.Wayflow
Wayflow rejects the same value with a
TypeErrorbecause it does not satisfy the expectedObjectProperty.This is the expected behavior.
Runtime Comparison
profile.activeImpact
An Agent Spec flow executed by the LangGraph runtime can successfully return values that violate the schema explicitly declared by its
EndNode.This makes the
EndNodeoutput contract unenforced and produces different behavior for the same Agent Spec across runtimes.