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

  1. Add all nodes with addNode before adding any edges, or ensure createGraph receives complete nodes and matching edges.
  2. Make edge source/target use the exact node.id values (same string, same casing).
  3. Filter edges whose endpoints are missing instead of adding them.
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/739ea4873a0a0625. Report an issue: GitHub.