donnemartin/interactive-coding-challenges · error · KeyError

Invalid key

Error message

Invalid key

What it means

Raised by Graph.add_edge when source_key or dest_key is None. Edges require real node keys on both endpoints; None would poison the nodes dict and adjacency lookups. Note this is a KeyError (not TypeError) for historical API consistency in this codebase.

Source

Thrown at graphs_trees/graph/graph.py:57

        del self.adj_weights[neighbor.key]
        del self.adj_nodes[neighbor.key]


class Graph:

    def __init__(self):
        self.nodes = {}  # Key = key, val = Node

    def add_node(self, key):
        if key is None:
            raise TypeError('key cannot be None')
        if key not in self.nodes:
            self.nodes[key] = Node(key)
        return self.nodes[key]

    def add_edge(self, source_key, dest_key, weight=0):
        if source_key is None or dest_key is None:
            raise KeyError('Invalid key')
        if source_key not in self.nodes:
            self.add_node(source_key)
        if dest_key not in self.nodes:
            self.add_node(dest_key)
        self.nodes[source_key].add_neighbor(self.nodes[dest_key], weight)

    def add_undirected_edge(self, src_key, dst_key, weight=0):
        if src_key is None or dst_key is None:
            raise TypeError('key cannot be None')
        self.add_edge(src_key, dst_key, weight)
        self.add_edge(dst_key, src_key, weight)

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Filter edge tuples containing None endpoints before calling add_edge
  2. Fix the upstream source of the None key (parser, config, join miss)
  3. Validate edges in a loop: if src is not None and dst is not None: add_edge(...)

Example fix

# before
for src, dst in edges:
    graph.add_edge(src, dst)  # KeyError on None

# after
for src, dst in edges:
    if src is not None and dst is not None:
        graph.add_edge(src, dst)
Defensive patterns

Strategy: validation

Validate before calling

if source_key is not None and dest_key is not None:
    graph.add_edge(source_key, dest_key)

Type guard

def valid_edge_keys(src, dst) -> bool:
    return src is not None and dst is not None

Try / catch

try:
    graph.add_edge(src, dst)
except KeyError as e:
    if 'Invalid key' in str(e):
        skip_or_log()
    else:
        raise

Prevention

When it happens

Trigger: Calling add_edge(None, 'b') or add_edge('a', None); indirectly via add_undirected_edge with a None endpoint.

Common situations: Building edge lists from data with missing endpoints; None leaking from parsing/config into edge tuples.

Related errors


AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28). Data as JSON: /api/errors/9eaec1bbf6af57bc. Report an issue: GitHub.