Skip to content

Commit b6f7af0

Browse files
committed
rename files
1 parent f4701b8 commit b6f7af0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+32554
-4
lines changed

src/oss/GRAPH_RECURSION_LIMIT.mdx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: GRAPH_RECURSION_LIMIT
3+
---
4+
Your LangGraph [`StateGraph`](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph) reached the maximum number of steps before hitting a stop condition.
5+
This is often due to an infinite loop caused by code like the example below:
6+
7+
:::python
8+
```python
9+
class State(TypedDict):
10+
some_key: str
11+
12+
builder = StateGraph(State)
13+
builder.add_node("a", ...)
14+
builder.add_node("b", ...)
15+
builder.add_edge("a", "b")
16+
builder.add_edge("b", "a")
17+
...
18+
19+
graph = builder.compile()
20+
```
21+
:::
22+
23+
:::js
24+
```typescript
25+
import { StateGraph } from "@langchain/langgraph";
26+
import { z } from "zod";
27+
28+
const State = z.object({
29+
someKey: z.string(),
30+
});
31+
32+
const builder = new StateGraph(State)
33+
.addNode("a", ...)
34+
.addNode("b", ...)
35+
.addEdge("a", "b")
36+
.addEdge("b", "a")
37+
...
38+
39+
const graph = builder.compile();
40+
```
41+
:::
42+
43+
However, complex graphs may hit the default limit naturally.
44+
45+
## Troubleshooting
46+
47+
* If you are not expecting your graph to go through many iterations, you likely have a cycle. Check your logic for infinite loops.
48+
49+
:::python
50+
* If you have a complex graph, you can pass in a higher `recursion_limit` value into your `config` object when invoking your graph like this:
51+
52+
```python
53+
graph.invoke({...}, {"recursion_limit": 100})
54+
```
55+
:::
56+
57+
:::js
58+
* If you have a complex graph, you can pass in a higher `recursionLimit` value into your `config` object when invoking your graph like this:
59+
60+
```typescript
61+
await graph.invoke({...}, { recursionLimit: 100 });
62+
```
63+
:::

src/oss/INVALID_CHAT_HISTORY.mdx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: INVALID_CHAT_HISTORY
3+
---
4+
:::python
5+
This error is raised in the prebuilt @[create_react_agent][create_react_agent] when the `call_model` graph node receives a malformed list of messages. Specifically, it is malformed when there are `AIMessages` with `tool_calls` (LLM requesting to call a tool) that do not have a corresponding `ToolMessage` (result of a tool invocation to return to the LLM).
6+
:::
7+
8+
:::js
9+
This error is raised in the prebuilt @[createReactAgent][create_react_agent] when the `callModel` graph node receives a malformed list of messages. Specifically, it is malformed when there are `AIMessage`s with `tool_calls` (LLM requesting to call a tool) that do not have a corresponding `ToolMessage` (result of a tool invocation to return to the LLM).
10+
:::
11+
12+
There could be a few reasons you're seeing this error:
13+
14+
:::python
15+
1. You manually passed a malformed list of messages when invoking the graph, e.g. `graph.invoke({'messages': [AIMessage(..., tool_calls=[...])]})`
16+
2. The graph was interrupted before receiving updates from the `tools` node (i.e. a list of ToolMessages)
17+
and you invoked it with an input that is not None or a ToolMessage,
18+
e.g. `graph.invoke({'messages': [HumanMessage(...)]}, config)`.
19+
This interrupt could have been triggered in one of the following ways:
20+
* You manually set `interrupt_before = ['tools']` in `create_react_agent`
21+
* One of the tools raised an error that wasn't handled by the @[ToolNode][ToolNode] (`"tools"`)
22+
:::
23+
24+
:::js
25+
1. You manually passed a malformed list of messages when invoking the graph, e.g. `graph.invoke({messages: [new AIMessage({..., tool_calls: [...]})]})`
26+
2. The graph was interrupted before receiving updates from the `tools` node (i.e. a list of ToolMessages)
27+
and you invoked it with an input that is not null or a ToolMessage,
28+
e.g. `graph.invoke({messages: [new HumanMessage(...)]}, config)`.
29+
This interrupt could have been triggered in one of the following ways:
30+
* You manually set `interruptBefore: ['tools']` in `createReactAgent`
31+
* One of the tools raised an error that wasn't handled by the @[ToolNode][ToolNode] (`"tools"`)
32+
:::
33+
34+
## Troubleshooting
35+
36+
To resolve this, you can do one of the following:
37+
38+
1. Don't invoke the graph with a malformed list of messages
39+
2. In case of an interrupt (manual or due to an error) you can:
40+
41+
:::python
42+
* provide ToolMessages that match existing tool calls and call `graph.invoke({'messages': [ToolMessage(...)]})`.
43+
**NOTE**: this will append the messages to the history and run the graph from the START node.
44+
* manually update the state and resume the graph from the interrupt:
45+
1. get the list of most recent messages from the graph state with `graph.get_state(config)`
46+
2. modify the list of messages to either remove unanswered tool calls from AIMessages
47+
48+
or add ToolMessages with tool_call_ids that match unanswered tool calls 3. call `graph.update_state(config, {'messages': ...})` with the modified list of messages 4. resume the graph, e.g. call `graph.invoke(None, config)`
49+
:::
50+
51+
:::js
52+
* provide ToolMessages that match existing tool calls and call `graph.invoke({messages: [new ToolMessage(...)]})`.
53+
**NOTE**: this will append the messages to the history and run the graph from the START node.
54+
* manually update the state and resume the graph from the interrupt:
55+
1. get the list of most recent messages from the graph state with `graph.getState(config)`
56+
2. modify the list of messages to either remove unanswered tool calls from AIMessages
57+
58+
or add ToolMessages with `toolCallId`s that match unanswered tool calls 3. call `graph.updateState(config, {messages: ...})` with the modified list of messages 4. resume the graph, e.g. call `graph.invoke(null, config)`
59+
:::
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
title: INVALID_CONCURRENT_GRAPH_UPDATE
3+
---
4+
A LangGraph [`StateGraph`](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph) received concurrent updates to its state from multiple nodes to a state property that doesn't
5+
support it.
6+
7+
One way this can occur is if you are using a [fanout](https://langchain-ai.github.io/langgraph/how-tos/map-reduce/)
8+
or other parallel execution in your graph and you have defined a graph like this:
9+
10+
:::python
11+
```python hl_lines="2"
12+
class State(TypedDict):
13+
some_key: str
14+
15+
def node(state: State):
16+
return {"some_key": "some_string_value"}
17+
18+
def other_node(state: State):
19+
return {"some_key": "some_string_value"}
20+
21+
22+
builder = StateGraph(State)
23+
builder.add_node(node)
24+
builder.add_node(other_node)
25+
builder.add_edge(START, "node")
26+
builder.add_edge(START, "other_node")
27+
graph = builder.compile()
28+
```
29+
:::
30+
31+
:::js
32+
```typescript hl_lines="2"
33+
import { StateGraph, Annotation, START } from "@langchain/langgraph";
34+
import { z } from "zod";
35+
36+
const State = z.object({
37+
someKey: z.string(),
38+
});
39+
40+
const builder = new StateGraph(State)
41+
.addNode("node", (state) => {
42+
return { someKey: "some_string_value" };
43+
})
44+
.addNode("otherNode", (state) => {
45+
return { someKey: "some_string_value" };
46+
})
47+
.addEdge(START, "node")
48+
.addEdge(START, "otherNode");
49+
50+
const graph = builder.compile();
51+
```
52+
:::
53+
54+
:::python
55+
If a node in the above graph returns `{ "some_key": "some_string_value" }`, this will overwrite the state value for `"some_key"` with `"some_string_value"`.
56+
However, if multiple nodes in e.g. a fanout within a single step return values for `"some_key"`, the graph will throw this error because
57+
there is uncertainty around how to update the internal state.
58+
:::
59+
60+
:::js
61+
If a node in the above graph returns `{ someKey: "some_string_value" }`, this will overwrite the state value for `someKey` with `"some_string_value"`.
62+
However, if multiple nodes in e.g. a fanout within a single step return values for `someKey`, the graph will throw this error because
63+
there is uncertainty around how to update the internal state.
64+
:::
65+
66+
To get around this, you can define a reducer that combines multiple values:
67+
68+
:::python
69+
```python hl_lines="5-6"
70+
import operator
71+
from typing import Annotated
72+
73+
class State(TypedDict):
74+
# The operator.add reducer fn makes this append-only
75+
some_key: Annotated[list, operator.add]
76+
```
77+
:::
78+
79+
:::js
80+
```typescript hl_lines="4-7"
81+
import { withLangGraph } from "@langchain/langgraph";
82+
import { z } from "zod";
83+
84+
const State = z.object({
85+
someKey: withLangGraph(z.array(z.string()), {
86+
reducer: {
87+
fn: (existing, update) => existing.concat(update),
88+
},
89+
default: () => [],
90+
}),
91+
});
92+
```
93+
:::
94+
95+
This will allow you to define logic that handles the same key returned from multiple nodes executed in parallel.
96+
97+
## Troubleshooting
98+
99+
The following may help resolve this error:
100+
101+
* If your graph executes nodes in parallel, make sure you have defined relevant state keys with a reducer.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
title: INVALID_GRAPH_NODE_RETURN_VALUE
3+
---
4+
:::python
5+
A LangGraph [`StateGraph`](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph)
6+
received a non-dict return type from a node. Here's an example:
7+
8+
```python
9+
class State(TypedDict):
10+
some_key: str
11+
12+
def bad_node(state: State):
13+
# Should return a dict with a value for "some_key", not a list
14+
return ["whoops"]
15+
16+
builder = StateGraph(State)
17+
builder.add_node(bad_node)
18+
...
19+
20+
graph = builder.compile()
21+
```
22+
23+
Invoking the above graph will result in an error like this:
24+
25+
```python
26+
graph.invoke({ "some_key": "someval" });
27+
```
28+
29+
```
30+
InvalidUpdateError: Expected dict, got ['whoops']
31+
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/INVALID_GRAPH_NODE_RETURN_VALUE
32+
```
33+
34+
Nodes in your graph must return a dict containing one or more keys defined in your state.
35+
:::
36+
37+
:::js
38+
A LangGraph [`StateGraph`](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph)
39+
received a non-object return type from a node. Here's an example:
40+
41+
```typescript
42+
import { z } from "zod";
43+
import { StateGraph } from "@langchain/langgraph";
44+
45+
const State = z.object({
46+
someKey: z.string(),
47+
});
48+
49+
const badNode = (state: z.infer<typeof State>) => {
50+
// Should return an object with a value for "someKey", not an array
51+
return ["whoops"];
52+
};
53+
54+
const builder = new StateGraph(State).addNode("badNode", badNode);
55+
// ...
56+
57+
const graph = builder.compile();
58+
```
59+
60+
Invoking the above graph will result in an error like this:
61+
62+
```typescript
63+
await graph.invoke({ someKey: "someval" });
64+
```
65+
66+
```
67+
InvalidUpdateError: Expected object, got ['whoops']
68+
For troubleshooting, visit: https://langchain-ai.github.io/langgraphjs/troubleshooting/errors/INVALID_GRAPH_NODE_RETURN_VALUE
69+
```
70+
71+
Nodes in your graph must return an object containing one or more keys defined in your state.
72+
:::
73+
74+
## Troubleshooting
75+
76+
The following may help resolve this error:
77+
78+
:::python
79+
* If you have complex logic in your node, make sure all code paths return an appropriate dict for your defined state.
80+
:::
81+
82+
:::js
83+
* If you have complex logic in your node, make sure all code paths return an appropriate object for your defined state.
84+
:::

src/oss/MULTIPLE_SUBGRAPHS.mdx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
title: MULTIPLE_SUBGRAPHS
3+
---
4+
You are calling subgraphs multiple times within a single LangGraph node with checkpointing enabled for each subgraph.
5+
6+
This is currently not allowed due to internal restrictions on how checkpoint namespacing for subgraphs works.
7+
8+
## Troubleshooting
9+
10+
The following may help resolve this error:
11+
12+
:::python
13+
* If you don't need to interrupt/resume from a subgraph, pass `checkpointer=False` when compiling it like this: `.compile(checkpointer=False)`
14+
:::
15+
16+
:::js
17+
* If you don't need to interrupt/resume from a subgraph, pass `checkpointer: false` when compiling it like this: `.compile({ checkpointer: false })`
18+
:::
19+
20+
* Don't imperatively call graphs multiple times in the same node, and instead use the [`Send`](https://langchain-ai.github.io/langgraph/concepts/low_level/#send) API.

0 commit comments

Comments
 (0)