{"record":{"id":"afaf6d7b30a8a9b7","repo":"trekhleb/javascript-algorithms","slug":"edge-not-found-in-graph","errorCode":null,"errorMessage":"Edge not found in graph","messagePattern":"Edge not found in graph","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/data-structures/graph/Graph.js","lineNumber":106,"sourceCode":"      startVertex.addEdge(edge);\n    } else {\n      // If graph ISN'T directed then add the edge to both vertices.\n      startVertex.addEdge(edge);\n      endVertex.addEdge(edge);\n    }\n\n    return this;\n  }\n\n  /**\n   * @param {GraphEdge} edge\n   */\n  deleteEdge(edge) {\n    // Delete edge from the list of edges.\n    if (this.edges[edge.getKey()]) {\n      delete this.edges[edge.getKey()];\n    } else {\n      throw new Error('Edge not found in graph');\n    }\n\n    // Try to find and end start vertices and delete edge from them.\n    const startVertex = this.getVertexByKey(edge.startVertex.getKey());\n    const endVertex = this.getVertexByKey(edge.endVertex.getKey());\n\n    startVertex.deleteEdge(edge);\n    endVertex.deleteEdge(edge);\n  }\n\n  /**\n   * @param {GraphVertex} startVertex\n   * @param {GraphVertex} endVertex\n   * @return {(GraphEdge|null)}\n   */\n  findEdge(startVertex, endVertex) {\n    const vertex = this.getVertexByKey(startVertex.getKey());\n","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/trekhleb/javascript-algorithms/blob/85293e3e2b88f4d2ce330d956b139cf628aa1e82/src/data-structures/graph/Graph.js#L88-L124","documentation":"Graph.deleteEdge() removes the entry under edge.getKey() from this.edges and throws at Graph.js:103-107 when that key is absent - deleting an edge the graph does not hold is treated as a bug, not a no-op. It then also strips the edge from both endpoint vertices. Because keys are direction-sensitive ('start_end'), an edge can be missing even when the reverse pair exists in an undirected graph.","triggerScenarios":"Calling deleteEdge(edge) twice (the first call removes the key); deleting an edge that was never added; constructing new GraphEdge(b, a) to delete an undirected edge that was stored under the a_b key; deleting after edge.reverse() or after endpoint mutation changed getKey().","commonSituations":"Cleanup loops that visit the same edge twice (iterating a copied edge list while queueing deletions); mixed endpoint ordering between the add path and the delete path; tests that delete fixture edges repeatedly without rebuilding the graph.","solutions":["Fetch the stored edge and delete that instance: const stored = graph.findEdge(u, v); if (stored) graph.deleteEdge(stored); - findEdge() matches both orientations.","Guard by key: if (graph.edges[edge.getKey()]) graph.deleteEdge(edge);","Delete in a single pass over graph.getAllEdges() and do not re-enqueue deletions.","Normalize endpoint order for undirected graphs before constructing the edge you delete."],"exampleFix":"// before\ngraph.deleteEdge(edge);\ngraph.deleteEdge(edge); // Error: Edge not found in graph\n\n// after\nconst stored = graph.findEdge(edge.startVertex, edge.endVertex);\nif (stored) {\n  graph.deleteEdge(stored);\n}","handlingStrategy":"validation","validationCode":"// findEdge() resolves either orientation and returns the stored instance\nconst stored = graph.findEdge(startVertex, endVertex);\nif (stored) {\n  graph.deleteEdge(stored);\n}","typeGuard":null,"tryCatchPattern":"try {\n  graph.deleteEdge(edge);\n} catch (error) {\n  if (error.message === 'Edge not found in graph') {\n    // already deleted or never added - treat as an idempotent no-op\n  } else {\n    throw error;\n  }\n}","preventionTips":["Delete only instances returned by getAllEdges()/findEdge(), never freshly constructed lookalikes.","Make deletion single-pass; do not queue the same edge for removal twice.","Remember keys are directional even in undirected graphs - normalize endpoint order or use findEdge().","Do not reuse an edge object for deletion after calling reverse() on it."],"tags":["graph","delete-edge","precondition","idempotency"],"backgroundTag":"no-such-element","analyzedSha":"85293e3e2b88f4d2ce330d956b139cf628aa1e82","analyzedAt":"2026-08-24T05:59:10.417Z","schemaVersion":2},"datasetVersion":"2026-08-24T07:17:09.176Z"}