krahets/hello-algo · error · Error

Illegal Argument Exception

Error message

Illegal Argument Exception

What it means

Thrown by GraphAdjList.addEdge() when either endpoint vertex is not present in the adjacency map, or when both arguments are the exact same vertex reference (self-loop). The implementation is an undirected graph keyed by Vertex object identity in a Map, so vertices must be registered via addVertex (or the constructor) before they can be connected.

Source

Thrown at codes/typescript/chapter_graph/graph_adjacency_list.ts:37

            this.addVertex(edge[0]);
            this.addVertex(edge[1]);
            this.addEdge(edge[0], edge[1]);
        }
    }

    /* 获取顶点数量 */
    size(): number {
        return this.adjList.size;
    }

    /* 添加边 */
    addEdge(vet1: Vertex, vet2: Vertex): void {
        if (
            !this.adjList.has(vet1) ||
            !this.adjList.has(vet2) ||
            vet1 === vet2
        ) {
            throw new Error('Illegal Argument Exception');
        }
        // 添加边 vet1 - vet2
        this.adjList.get(vet1).push(vet2);
        this.adjList.get(vet2).push(vet1);
    }

    /* 删除边 */
    removeEdge(vet1: Vertex, vet2: Vertex): void {
        if (
            !this.adjList.has(vet1) ||
            !this.adjList.has(vet2) ||
            vet1 === vet2 ||
            this.adjList.get(vet1).indexOf(vet2) === -1
        ) {
            throw new Error('Illegal Argument Exception');
        }
        // 删除边 vet1 - vet2
        this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);

View on GitHub (pinned to 69932aed18)

Solutions

  1. Register both vertices first: graph.addVertex(v1); graph.addVertex(v2); before addEdge, or construct the graph from an edges array that does this.
  2. Reuse the exact Vertex object references stored in the graph — never reconstruct equivalent Vertices by value.
  3. Reject self-loops at the call site: if (v1 !== v2) graph.addEdge(v1, v2).
  4. Keep a registry (Map<val, Vertex>) so you always retrieve the canonical vertex instance by value.

Example fix

// before
const a = new Vertex(1); graph.addEdge(a, a); // throws: self-loop
const b = new Vertex(2); graph.addEdge(a, b); // throws if b not added
// after
const a = new Vertex(1), b = new Vertex(2);
graph.addVertex(a); graph.addVertex(b);
if (a !== b) graph.addEdge(a, b);
Defensive patterns

Strategy: validation

Validate before calling

function safeAddEdge(graph, v1, v2) {
  if (v1 === v2) return false; // no self-loops
  if (!graph.adjList.has(v1) || !graph.adjList.has(v2)) return false;
  graph.addEdge(v1, v2);
  return true;
}

Type guard

// Vertex identity guard: ensure the exact stored reference is used
function isKnownVertex(graph, v) {
  return graph.adjList.has(v);
}

Try / catch

null

Prevention

When it happens

Trigger: Calling addEdge(v1, v2) where v1 or v2 was never added with addVertex; passing two references to the same Vertex instance (vet1 === vet2); passing a newly-constructed Vertex that is equal-by-value but not identical-by-reference to the one stored in the graph (Map uses reference equality for objects).

Common situations: Creating a fresh new Vertex(val) with the same value as an existing vertex and expecting it to resolve — Map.has() uses reference identity, so a value-duplicate but distinct object is treated as absent; forgetting to call addVertex before addEdge; attempting to model a self-loop in a graph that forbids them.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/7c46d0944637657f. Report an issue: GitHub.