trekhleb/javascript-algorithms · error · Error
Edge has already been added before
Error message
Edge has already been added before
What it means
Graph.addEdge() indexes edges by edge.getKey(), which GraphEdge computes as `${startVertex.getKey()}_${endVertex.getKey()}` (or a custom key passed to its constructor). After auto-inserting missing endpoint vertices, the guard at Graph.js:79-83 refuses a second edge with the same key, so the graph holds at most one edge per ordered vertex pair. The check is direction-aware even in undirected graphs: keys A_B and B_A are different.
Source
Thrown at src/data-structures/graph/Graph.js:80
// Try to find and end start vertices.
let startVertex = this.getVertexByKey(edge.startVertex.getKey());
let endVertex = this.getVertexByKey(edge.endVertex.getKey());
// Insert start vertex if it wasn't inserted.
if (!startVertex) {
this.addVertex(edge.startVertex);
startVertex = this.getVertexByKey(edge.startVertex.getKey());
}
// Insert end vertex if it wasn't inserted.
if (!endVertex) {
this.addVertex(edge.endVertex);
endVertex = this.getVertexByKey(edge.endVertex.getKey());
}
// Check if edge has been already added.
if (this.edges[edge.getKey()]) {
throw new Error('Edge has already been added before');
} else {
this.edges[edge.getKey()] = edge;
}
// Add edge to the vertices.
if (this.isDirected) {
// If graph IS directed then add the edge only to start vertex.
startVertex.addEdge(edge);
} else {
// If graph ISN'T directed then add the edge to both vertices.
startVertex.addEdge(edge);
endVertex.addEdge(edge);
}
return this;
}
/**View on GitHub (pinned to 85293e3e2b)
Solutions
- Check before adding: if (!graph.findEdge(start, end)) graph.addEdge(new GraphEdge(start, end)); - findEdge() matches either orientation, which matters for undirected graphs.
- Deduplicate the input edge list first on a canonical `${u}_${v}` key before inserting anything.
- Model multiplicity with weight instead of parallel edges: find the existing edge via findEdge() and increase its weight.
- If edges carry a custom key, make sure keys are unique per edge.
Example fix
// before
graph.addEdge(new GraphEdge(a, b));
graph.addEdge(new GraphEdge(a, b)); // Error: Edge has already been added before
// after
const edge = new GraphEdge(a, b);
if (!graph.findEdge(a, b)) {
graph.addEdge(edge);
} Defensive patterns
Strategy: validation
Validate before calling
// findEdge() returns the stored edge for either orientation (undirected-safe)
if (!graph.findEdge(startVertex, endVertex)) {
graph.addEdge(new GraphEdge(startVertex, endVertex));
} Try / catch
try {
graph.addEdge(edge);
} catch (error) {
if (error.message === 'Edge has already been added before') {
const existing = graph.findEdge(edge.startVertex, edge.endVertex);
existing.weight += edge.weight; // fold duplicates into weight, if meaningful
} else {
throw error;
}
} Prevention
- Deduplicate edge pairs at ingest time on a canonical `${min}_${max}` (undirected) or `${u}_${v}` (directed) key.
- Check graph.findEdge() before every addEdge() when input is not guaranteed unique.
- Represent multiplicity as edge weight, not repeated edges - this structure is not a multigraph.
- Keep custom edge keys unique; they bypass the auto-generated key.
When it happens
Trigger: graph.addEdge(edge) called twice with the same GraphEdge object; two different GraphEdge instances joining the same pair in the same direction; an input edge list containing duplicate rows; two edges sharing an explicit custom key passed as new GraphEdge(start, end, weight, key).
Common situations: Importing adjacency lists or CSV edge data with duplicate pairs; retry/re-sync logic that re-adds edges after a partial failure; attempting to model parallel edges (a multigraph) - this structure cannot represent them, so the second insert throws.
Related errors
AI-assisted analysis of trekhleb/javascript-algorithms@85293e3e2b (2026-08-24).
Data as JSON: /api/errors/e5fcfbdb56f45249.
Report an issue: GitHub.