krahets/hello-algo · error · Error

Illegal Argument Exception

Error message

Illegal Argument Exception

What it means

Thrown by addEdge(vet1, vet2) in an adjacency-list graph when either vertex is absent from the Map, or when vet1 === vet2 (self-loops disallowed). Map keys use reference identity (SameValueZero), so a vertex object with the same val but a different reference is treated as absent. The guard prevents calling .push on an undefined adjacency list.

Source

Thrown at zh-hant/codes/javascript/chapter_graph/graph_adjacency_list.js:37

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

    /* 獲取頂點數量 */
    size() {
        return this.adjList.size;
    }

    /* 新增邊 */
    addEdge(vet1, vet2) {
        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, vet2) {
        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. Add both vertices via addVertex (or the constructor edges) before calling addEdge, using the same object references.
  2. Guard the call: if (adjList.has(vet1) && adjList.has(vet2) && vet1 !== vet2) graph.addEdge(vet1, vet2);
  3. If val-based identity is needed, key the Map by a primitive id instead of the Vertex object.
  4. Wrap in try/catch when adding edges from untrusted sources.

Example fix

// before
graph.addEdge(new Vertex(1), new Vertex(2)); // refs not stored -> throws

// after
const v1 = new Vertex(1), v2 = new Vertex(2);
graph.addVertex(v1);
graph.addVertex(v2);
graph.addEdge(v1, v2);
Defensive patterns

Strategy: validation

Validate before calling

if (
    graph.adjList.has(vet1) &&
    graph.adjList.has(vet2) &&
    vet1 !== vet2
) {
    graph.addEdge(vet1, vet2);
}

Type guard

function canAddEdge(graph, vet1, vet2) {
    return (
        graph.adjList.has(vet1) &&
        graph.adjList.has(vet2) &&
        vet1 !== vet2
    );
}

Try / catch

try {
    graph.addEdge(vet1, vet2);
} catch (e) {
    if (e instanceof Error && e.message === 'Illegal Argument Exception') {
        // vertices missing or self-loop; skip or log
    } else throw e;
}

Prevention

When it happens

Trigger: Calling addEdge with a Vertex not previously added via the constructor or addVertex; passing two different references that represent the same logical vertex; attempting addEdge(v, v) to form a self-loop.

Common situations: Deserializing vertices from storage and passing new instances to addEdge; aliasing bugs where two Vertex objects share a val but differ in reference; graph algorithms that try self-loops.

Related errors


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