krahets/hello-algo · error · Error

Illegal Argument Exception

Error message

Illegal Argument Exception

What it means

Thrown by the TypeScript adjacency-list graph's addEdge when either endpoint is not a registered Vertex (adjList.has fails), or when both arguments are the same reference (self-loop disallowed). The Vertex type is enforced at compile time, but existence in the Map and distinctness are runtime checks. The guard protects the subsequent .push calls from undefined neighbor lists.

Source

Thrown at ja/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. Call addVertex for both endpoints and pass back the exact stored references.
  2. Maintain a Map<number, Vertex> keyed by val to always retrieve the canonical instance.
  3. Guard against vet1 === vet2 before calling addEdge.
  4. Expose a hasVertex(vet) helper and check it at the call site.

Example fix

// before
graph.addEdge(new Vertex(1), v2);  // new instance not in graph -> throws

// after
const v1 = vertexById.get(1)!;  // retrieve stored reference
graph.addEdge(v1, v2);
Defensive patterns

Strategy: type-guard

Validate before calling

function safeAddEdge(graph: GraphAdjacencyList, vet1: Vertex, vet2: Vertex): boolean {
  if (vet1 === vet2) return false;
  if (!graph.adjList.has(vet1) || !graph.adjList.has(vet2)) return false;
  graph.addEdge(vet1, vet2);
  return true;
}

Type guard

const isRegisteredVertex = (graph: GraphAdjacencyList, v: Vertex): boolean =>
  graph.adjList.has(v);

Try / catch

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

Prevention

When it happens

Trigger: Calling addEdge(vet1, vet2) where vet1/vet2 were not added via addVertex; passing the same Vertex reference twice; passing a Vertex equal-by-val but distinct-by-reference from the stored key (Map uses reference equality).

Common situations: TypeScript guarantees the type but not graph membership; forgetting addVertex; reconstructing a Vertex from its val field instead of retrieving the stored instance; building edges before vertices.

Related errors


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