{"record":{"id":"95fa74ae420f052e","repo":"mastra-ai/mastra","slug":"edge-references-unknown-node-edge-source","errorCode":null,"errorMessage":"Edge references unknown node: ${edge.source}","messagePattern":"Edge references unknown node: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/rag/src/graph-rag/index.ts","lineNumber":154,"sourceCode":"    if (snapshot?.version !== GRAPH_RAG_SNAPSHOT_VERSION) {\n      throw new Error(`Unsupported GraphRAG snapshot version: ${snapshot?.version}`);\n    }\n\n    const graph = new GraphRAG(snapshot.dimension, snapshot.threshold);\n\n    for (const node of snapshot.nodes ?? []) {\n      // Route through addNode so embedding presence and dimension are validated\n      // at load time rather than failing later inside query().\n      graph.addNode({\n        ...node,\n        ...(node.embedding ? { embedding: [...node.embedding] } : {}),\n        ...(node.metadata ? { metadata: structuredClone(node.metadata) } : {}),\n      });\n    }\n\n    for (const edge of snapshot.edges ?? []) {\n      if (!graph.nodes.has(edge.source)) {\n        throw new Error(`Edge references unknown node: ${edge.source}`);\n      }\n      if (!graph.nodes.has(edge.target)) {\n        throw new Error(`Edge references unknown node: ${edge.target}`);\n      }\n    }\n\n    // Assign directly rather than via addEdge: the serialized edge list already\n    // contains both directions, and addEdge would add the reverse edge again.\n    graph.edges = (snapshot.edges ?? []).map(edge => ({ ...edge }));\n\n    return graph;\n  }\n\n  clear(): void {\n    this.nodes.clear();\n    this.edges = [];\n  }\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/rag/src/graph-rag/index.ts#L136-L172","documentation":"During deserialize(), every snapshot edge must reference nodes that exist in the snapshot's node list. If edge.source is not found among the restored nodes, the graph would be internally inconsistent, so deserialize throws. This protects against corrupted or hand-edited snapshots.","triggerScenarios":"Calling GraphRAG.deserialize(snapshot) where snapshot.edges contains an edge whose source id is not present in snapshot.nodes — e.g. nodes were filtered out, ids were renamed, or the edges array was hand-written.","commonSituations":"Manually pruning nodes from a serialized snapshot without pruning dependent edges; changing node id schemes between exports; merging snapshots from two graphs with different id spaces; partially truncated JSON that lost node entries but kept edges.","solutions":["Ensure every edge's source/target exists in snapshot.nodes; filter out dangling edges before deserializing.","Rebuild the snapshot from the live graph with serialize() instead of hand-editing persisted JSON.","If node ids were remapped, remap edge source/target ids in the same migration.","Validate the snapshot offline: build a Set of node ids and drop edges not present in it."],"exampleFix":"// before\nconst graph = GraphRAG.deserialize(snapshot);\n// after\nconst ids = new Set(snapshot.nodes.map(n => n.id));\nsnapshot.edges = snapshot.edges.filter(e => ids.has(e.source) && ids.has(e.target));\nconst graph = GraphRAG.deserialize(snapshot);","handlingStrategy":"validation","validationCode":"const ids = new Set(snapshot.nodes.map(n => n.id));\nconst dangling = snapshot.edges.filter(e => !ids.has(e.source));\nif (dangling.length) throw new Error(`Edges with unknown source: ${dangling.map(e => e.source).join(',')}`);","typeGuard":"const edgesHaveKnownSources = (s: GraphRAGSnapshot): boolean => {\n  const ids = new Set(s.nodes.map(n => n.id));\n  return s.edges.every(e => ids.has(e.source));\n};","tryCatchPattern":"try {\n  const graph = GraphRAG.deserialize(snapshot);\n} catch (e) {\n  if ((e as Error).message.startsWith('Edge references unknown node')) {\n    // sanitize snapshot: drop dangling edges, then retry\n  } else throw e;\n}","preventionTips":["Never prune nodes from a snapshot without pruning dependent edges","Validate referential integrity of snapshots before loading","Regenerate snapshots with serialize() instead of hand-editing JSON","Keep node id schemes stable across exports"],"tags":["serialization","graph-integrity","rag","dangling-reference"],"backgroundTag":"dangling-reference","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}