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

  1. Check before adding: if (!graph.findEdge(start, end)) graph.addEdge(new GraphEdge(start, end)); - findEdge() matches either orientation, which matters for undirected graphs.
  2. Deduplicate the input edge list first on a canonical `${u}_${v}` key before inserting anything.
  3. Model multiplicity with weight instead of parallel edges: find the existing edge via findEdge() and increase its weight.
  4. 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

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.