graph.addEdge method fails when adding an edge to END #29

Closed
opened 2026-02-15 17:05:48 -05:00 by yindo · 14 comments
Owner

Originally created by @jamesfdavis on GitHub (May 25, 2024).

When attempting to add an edge from a node to END in a MessageGraph, the graph.addEdge method fails. The method signature seems to indicate that the endKey parameter should accept typeof END, but it throws an error instead.

Steps to Reproduce

  1. Import the necessary modules.
  2. Create a new MessageGraph.
  3. Add a node.
  4. Attempt to add an edge to END.

Expected Behavior

The edge should be added without errors.

Actual Behavior

The method throws an error indicating a type mismatch.

Argument of type '"oracle"' is not assignable to parameter of type '"__start__" | "__start__"[]'.

Versions

  • TypeScript: 5.4.5
  • @langchain/openai: 0.0.33
  • @langchain/core: 0.2.0
  • @langchain/langgraph: 0.0.21

Code

import { ChatOpenAI } from "@langchain/openai";
import { BaseMessage } from "@langchain/core/messages";
import { END, MessageGraph } from "@langchain/langgraph";

const model = new ChatOpenAI({ temperature: 0 });

const graph = new MessageGraph();

graph.addNode("oracle", async (state: BaseMessage[]) => {
  return model.invoke(state);
});

try {
  graph.addEdge("oracle", END);  // This line fails
} catch (error) {
  console.error(error);
}

graph.setEntryPoint("oracle");
const runnable = graph.compile();

Operating System

ProductName: macOS
ProductVersion: 14.5
BuildVersion: 23F79

Runtime

NodeJS: v20.13.1

Final Thoughts

After testing the addEdge method in other projects, the error seems very consistent and does not seem to be only associated with the END const variable. This error also happens with StateGraph implementation.

Originally created by @jamesfdavis on GitHub (May 25, 2024). When attempting to add an edge from a node to `END` in a `MessageGraph`, the `graph.addEdge` method fails. The method signature seems to indicate that the `endKey` parameter should accept `typeof END`, but it throws an error instead. #### Steps to Reproduce 1. Import the necessary modules. 2. Create a new `MessageGraph`. 3. Add a node. 4. Attempt to add an edge to `END`. #### Expected Behavior The edge should be added without errors. #### Actual Behavior The method throws an error indicating a type mismatch. `Argument of type '"oracle"' is not assignable to parameter of type '"__start__" | "__start__"[]'.` #### Versions - TypeScript: 5.4.5 - @langchain/openai: 0.0.33 - @langchain/core: 0.2.0 - @langchain/langgraph: 0.0.21 #### Code ```typescript import { ChatOpenAI } from "@langchain/openai"; import { BaseMessage } from "@langchain/core/messages"; import { END, MessageGraph } from "@langchain/langgraph"; const model = new ChatOpenAI({ temperature: 0 }); const graph = new MessageGraph(); graph.addNode("oracle", async (state: BaseMessage[]) => { return model.invoke(state); }); try { graph.addEdge("oracle", END); // This line fails } catch (error) { console.error(error); } graph.setEntryPoint("oracle"); const runnable = graph.compile(); ``` #### Operating System ProductName: macOS ProductVersion: 14.5 BuildVersion: 23F79 #### Runtime NodeJS: v20.13.1 #### Final Thoughts After testing the addEdge method in other projects, the error seems very consistent and does not seem to be only associated with the END const variable. This error also happens with StateGraph implementation.
yindo closed this issue 2026-02-15 17:05:48 -05:00
Author
Owner

@hinthornw commented on GitHub (May 25, 2024):

Does it work if you create it functionally (like I do in a lot of the how tos)

const graph = new MessageGraph().addNode("oracle", async (state: BaseMessage[]) => {
  return model.invoke(state);
});
@hinthornw commented on GitHub (May 25, 2024): Does it work if you create it functionally (like I do in a lot of the how tos) ``` const graph = new MessageGraph().addNode("oracle", async (state: BaseMessage[]) => { return model.invoke(state); }); ```
Author
Owner

@jamesfdavis commented on GitHub (May 25, 2024):

@hinthornw - After reviewing the how-to examples, I found that I was not chaining the builder.

I adapted my example from the README, so this might be a change the team wants to include in the README.

import { ChatOpenAI } from "@langchain/openai";
import { BaseMessage, } from "@langchain/core/messages";
import { START, END, MessageGraph } from "@langchain/langgraph";

const model = new ChatOpenAI({ temperature: 0 });
const graph = new MessageGraph()
.addNode("oracle", async (state: BaseMessage[]) => {
  return model.invoke(state);
})
.addEdge("oracle", END)
.addEdge(START,"oracle");

const runnable = graph.compile();

Thanks for the feedback, it had me digging deeper for an answer.

@jamesfdavis commented on GitHub (May 25, 2024): @hinthornw - After reviewing the how-to examples, I found that I was not chaining the builder. I adapted my example from the README, so this might be a change the team wants to include in the README. ```ts import { ChatOpenAI } from "@langchain/openai"; import { BaseMessage, } from "@langchain/core/messages"; import { START, END, MessageGraph } from "@langchain/langgraph"; const model = new ChatOpenAI({ temperature: 0 }); const graph = new MessageGraph() .addNode("oracle", async (state: BaseMessage[]) => { return model.invoke(state); }) .addEdge("oracle", END) .addEdge(START,"oracle"); const runnable = graph.compile(); ``` Thanks for the feedback, it had me digging deeper for an answer.
Author
Owner

@hinthornw commented on GitHub (May 26, 2024):

Thanks for sharing! I should fix up the generic typing in the readme

@hinthornw commented on GitHub (May 26, 2024): Thanks for sharing! I should fix up the generic typing in the readme
Author
Owner

@gruckion commented on GitHub (May 27, 2024):

This issue should not be closed as the docs have not been updated.

https://github.com/langchain-ai/langgraphjs

import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, BaseMessage, } from "@langchain/core/messages";
import { END, MessageGraph } from "@langchain/langgraph";

const model = new ChatOpenAI({ temperature: 0 });

const graph = new MessageGraph();

graph.addNode("oracle", async (state: BaseMessage[]) => {
  return model.invoke(state);
});

graph.addEdge("oracle", END);

graph.setEntryPoint("oracle");

const runnable = graph.compile();

Should be updated to

import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, BaseMessage } from "@langchain/core/messages";
import { END, MessageGraph } from "@langchain/langgraph";

const model = new ChatOpenAI({ temperature: 0 });

const graph = new MessageGraph().addNode(
  "oracle",
  async (state: BaseMessage[]) => {
    return model.invoke(state);
  }
);

graph.addEdge("oracle", END);

graph.setEntryPoint("oracle");

const runnable = graph.compile();

Or

import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, BaseMessage } from "@langchain/core/messages";
import { END, MessageGraph, START } from "@langchain/langgraph";

require("dotenv").config();

const model = new ChatOpenAI({ temperature: 0 });

const graph = new MessageGraph().addNode(
  "oracle",
  async (state: BaseMessage[]) => {
    return model.invoke(state);
  }
);

graph.addEdge("oracle", END);

graph.addEdge(START, "oracle");

const runnable = graph.compile();
@gruckion commented on GitHub (May 27, 2024): This issue should not be closed as the docs have not been updated. https://github.com/langchain-ai/langgraphjs ```ts import { ChatOpenAI } from "@langchain/openai"; import { HumanMessage, BaseMessage, } from "@langchain/core/messages"; import { END, MessageGraph } from "@langchain/langgraph"; const model = new ChatOpenAI({ temperature: 0 }); const graph = new MessageGraph(); graph.addNode("oracle", async (state: BaseMessage[]) => { return model.invoke(state); }); graph.addEdge("oracle", END); graph.setEntryPoint("oracle"); const runnable = graph.compile(); ``` Should be updated to ```ts import { ChatOpenAI } from "@langchain/openai"; import { HumanMessage, BaseMessage } from "@langchain/core/messages"; import { END, MessageGraph } from "@langchain/langgraph"; const model = new ChatOpenAI({ temperature: 0 }); const graph = new MessageGraph().addNode( "oracle", async (state: BaseMessage[]) => { return model.invoke(state); } ); graph.addEdge("oracle", END); graph.setEntryPoint("oracle"); const runnable = graph.compile(); ``` Or ```ts import { ChatOpenAI } from "@langchain/openai"; import { HumanMessage, BaseMessage } from "@langchain/core/messages"; import { END, MessageGraph, START } from "@langchain/langgraph"; require("dotenv").config(); const model = new ChatOpenAI({ temperature: 0 }); const graph = new MessageGraph().addNode( "oracle", async (state: BaseMessage[]) => { return model.invoke(state); } ); graph.addEdge("oracle", END); graph.addEdge(START, "oracle"); const runnable = graph.compile(); ```
Author
Owner

@jamesfdavis commented on GitHub (May 27, 2024):

Re-opening the issue until it can be updated in the docs. re: @gruckion

@jamesfdavis commented on GitHub (May 27, 2024): Re-opening the issue until it can be updated in the docs. re: @gruckion
Author
Owner

@hinthornw commented on GitHub (May 31, 2024):

Alright, all, I went through all the tutorials in the docs, all the how-tos, and the README and rewrote them, compiled with TSC and ran in typescript with no complaints. Hopefully this resolves this issue. WIll keep open another day or two to let others push back but then will close

Thanks again to everyone on this thread (and others) for your patience and for calling out the breaks - going through this process definitely highlighted how much of a pain in the rear it is to go from the deno docs to TS

@hinthornw commented on GitHub (May 31, 2024): Alright, all, I went through all the tutorials in the docs, all the how-tos, and the README and rewrote them, compiled with TSC and ran in typescript with no complaints. Hopefully this resolves this issue. WIll keep open another day or two to let others push back but then will close Thanks again to everyone on this thread (and others) for your patience and for calling out the breaks - going through this process definitely highlighted how much of a pain in the rear it is to go from the deno docs to TS
Author
Owner

@afuentes commented on GitHub (Jun 2, 2024):

I am using this approach as a workaround to delete the below message.
Argument of type '"oracle"' is not assignable to parameter of type '"start" | "start"[]'.

const graph = new MessageGraph()

....

graph.addEdge(START,"oracle" as any)
graph.addEdge("oracle" as any ,END)

return graph

@afuentes commented on GitHub (Jun 2, 2024): I am using this approach as a workaround to delete the below message. Argument of type '"oracle"' is not assignable to parameter of type '"__start__" | "__start__"[]'. ```javascript const graph = new MessageGraph() .... graph.addEdge(START,"oracle" as any) graph.addEdge("oracle" as any ,END) return graph ```
Author
Owner

@hinthornw commented on GitHub (Jun 3, 2024):

@afuentes have you tried adding the nodes first before the edges?

const graph = new MessageGraph()
    .addNode("oracle", ...);
graph.addEdge(START, "oracle");
graph.addEdge("oracle" as any ,END)
@hinthornw commented on GitHub (Jun 3, 2024): @afuentes have you tried adding the nodes first before the edges? ``` const graph = new MessageGraph() .addNode("oracle", ...); graph.addEdge(START, "oracle"); graph.addEdge("oracle" as any ,END) ```
Author
Owner

@hinthornw commented on GitHub (Jun 5, 2024):

Seems like folks are no longer running into this? As always, feel free to re-open if there are still issues here

@hinthornw commented on GitHub (Jun 5, 2024): Seems like folks are no longer running into this? As always, feel free to re-open if there are still issues here
Author
Owner

@austinm911 commented on GitHub (Jul 27, 2024):

Seems like folks are no longer running into this? As always, feel free to re-open if there are still issues here

There are still type errors

const graph = new MessageGraph()

graph.addNode('oracle', async (state: BaseMessage[]) => {
	return llm.invoke(state)
})

graph.addEdge(START, 'oracle')
// Argument of type '"oracle"' is not assignable to parameter of type '"__start__" | "__end__"'
graph.addEdge('oracle', END)
// Argument of type '"oracle"' is not assignable to parameter of type '"__start__" | "__end__"'

const runnable = graph.compile()

const run = await runnable.invoke(new HumanMessage('What is 1 + 1?'))
console.log(run)
@austinm911 commented on GitHub (Jul 27, 2024): > Seems like folks are no longer running into this? As always, feel free to re-open if there are still issues here There are still type errors ```ts const graph = new MessageGraph() graph.addNode('oracle', async (state: BaseMessage[]) => { return llm.invoke(state) }) graph.addEdge(START, 'oracle') // Argument of type '"oracle"' is not assignable to parameter of type '"__start__" | "__end__"' graph.addEdge('oracle', END) // Argument of type '"oracle"' is not assignable to parameter of type '"__start__" | "__end__"' const runnable = graph.compile() const run = await runnable.invoke(new HumanMessage('What is 1 + 1?')) console.log(run) ```
Author
Owner

@christopherbauer commented on GitHub (Aug 7, 2024):

@hinthornw

Seems like folks are no longer running into this? As always, feel free to re-open if there are still issues here

You must chain the calls to get proper type checking (which is great IMO) but due to the example not reflecting this, people are getting confused. See @austinm911 's example, which works correctly if rewritten as:

const graph = new MessageGraph()

graph
       .addNode('oracle', async (state: BaseMessage[]) => {
	     return llm.invoke(state)
       })
       // Note - Add more nodes before constructing your edges to enable them as options to addEdge()
       .addEdge(START, 'oracle')
       .addEdge('oracle', END);

const runnable = graph.compile()

const run = await runnable.invoke(new HumanMessage('What is 1 + 1?'))
console.log(run)


Note that you cannot make multiple graph.addX() calls, you must do graph.addX().addX().addX

@christopherbauer commented on GitHub (Aug 7, 2024): @hinthornw > Seems like folks are no longer running into this? As always, feel free to re-open if there are still issues here You must chain the calls to get proper type checking (which is great IMO) but due to the example not reflecting this, people are getting confused. See @austinm911 's example, which works correctly if rewritten as: ``` const graph = new MessageGraph() graph .addNode('oracle', async (state: BaseMessage[]) => { return llm.invoke(state) }) // Note - Add more nodes before constructing your edges to enable them as options to addEdge() .addEdge(START, 'oracle') .addEdge('oracle', END); const runnable = graph.compile() const run = await runnable.invoke(new HumanMessage('What is 1 + 1?')) console.log(run) ``` Note that you cannot make multiple `graph.addX()` calls, you must do `graph.addX().addX().addX`
Author
Owner

@gabrieljbaker commented on GitHub (Nov 4, 2024):

It's sort of unbelievable that the docs still don't reflect the issue detailed above ^

@gabrieljbaker commented on GitHub (Nov 4, 2024): It's sort of unbelievable that the docs still don't reflect the issue detailed above ^
Author
Owner

@stonyme commented on GitHub (Apr 2, 2025):

This problem has been bothering me for a long time, and I want to give up the TS version. I know I see it here.

@stonyme commented on GitHub (Apr 2, 2025): This problem has been bothering me for a long time, and I want to give up the TS version. I know I see it here.
Author
Owner

@zerobell-lee commented on GitHub (Apr 27, 2025):

Why is this closed? I don't get it at all.

@zerobell-lee commented on GitHub (Apr 27, 2025): Why is this closed? I don't get it at all.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraphjs#29