mastra-ai/mastra · error
Both source and target nodes must exist
Error message
Both source and target nodes must exist
What it means
addEdge requires that both endpoints of an edge already exist as nodes in the graph, because edges are validated against node IDs and a reverse edge is also inserted. If either edge.source or edge.target is not a registered node ID, the edge is rejected. This keeps the graph internally consistent.
Source
Thrown at packages/rag/src/graph-rag/index.ts:80
this.dimension = dimension;
this.threshold = threshold;
}
// Add a node to the graph
addNode(node: GraphNode): void {
if (!node.embedding) {
throw new Error('Node must have an embedding');
}
if (node.embedding.length !== this.dimension) {
throw new Error(`Embedding dimension must be ${this.dimension}`);
}
this.nodes.set(node.id, node);
}
// Add an edge between two nodes
addEdge(edge: GraphEdge): void {
if (!this.nodes.has(edge.source) || !this.nodes.has(edge.target)) {
throw new Error('Both source and target nodes must exist');
}
this.edges.push(edge);
// Add reverse edge
this.edges.push({
source: edge.target,
target: edge.source,
weight: edge.weight,
type: edge.type,
});
}
// Helper method to get all nodes
getNodes(): GraphNode[] {
return Array.from(this.nodes.values());
}
// Helper method to get all edges
getEdges(): GraphEdge[] {View on GitHub (pinned to 75dd419e61)
Solutions
- Add all nodes with addNode before adding any edges, or ensure createGraph receives complete nodes and matching edges.
- Make edge source/target use the exact node.id values (same string, same casing).
- Filter edges whose endpoints are missing instead of adding them.
- If edges are LLM-generated, map entity names to actual node IDs before calling addEdge.
Example fix
// before
graph.addEdge({ source: 'doc1', target: 'doc2' }); // nodes not added yet
// after
graph.addNode({ id: 'doc1', content, embedding: e1 });
graph.addNode({ id: 'doc2', content, embedding: e2 });
graph.addEdge({ source: 'doc1', target: 'doc2', weight: 0.8 }); Defensive patterns
Strategy: validation
Validate before calling
const ids = new Set(nodes.map(n => n.id));
const dangling = edges.filter(e => !ids.has(e.source) || !ids.has(e.target));
if (dangling.length) throw new Error(`Edges reference missing nodes: ${dangling.map(e => `${e.source}->${e.target}`).join(', ')}`); Try / catch
try {
graph.addEdge(edge);
} catch (e) {
if ((e as Error).message === 'Both source and target nodes must exist') {
console.warn(`Skipping edge ${edge.source}->${edge.target}: endpoint node missing`);
return;
}
throw e;
} Prevention
- Add all nodes before any edges; build edges only from the final node set.
- Use node.id verbatim as edge source/target — never entity labels or display names.
- Filter edges after any node pruning/dedup step.
- Validate edge endpoints with a Set lookup before addEdge or createGraph.
When it happens
Trigger: Calling addEdge({ source: 'a', target: 'b' }) before addNode was called for 'a' or 'b'; building edges from a separate metadata file whose IDs don't match node IDs; createGraph receiving an edges array referencing pruned/filtered nodes.
Common situations: Generating edges from LLM output referencing entity names instead of node IDs; deduplication/filtering that removed nodes after edges were computed; id mismatches like 'doc-1' vs '1' between the node builder and edge builder.
Related errors
- Node must have an embedding
- HTML chunking requires either headers or sections to be spec
- JSON chunking requires maxSize to be specified
- Sentence chunking requires maxSize to be specified
- Keywords must be greater than 0
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/739ea4873a0a0625.
Report an issue: GitHub.