{"record":{"id":"9eaec1bbf6af57bc","repo":"donnemartin/interactive-coding-challenges","slug":"invalid-key","errorCode":null,"errorMessage":"Invalid key","messagePattern":"Invalid key","errorType":"validation","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"graphs_trees/graph/graph.py","lineNumber":57,"sourceCode":"        del self.adj_weights[neighbor.key]\n        del self.adj_nodes[neighbor.key]\n\n\nclass Graph:\n\n    def __init__(self):\n        self.nodes = {}  # Key = key, val = Node\n\n    def add_node(self, key):\n        if key is None:\n            raise TypeError('key cannot be None')\n        if key not in self.nodes:\n            self.nodes[key] = Node(key)\n        return self.nodes[key]\n\n    def add_edge(self, source_key, dest_key, weight=0):\n        if source_key is None or dest_key is None:\n            raise KeyError('Invalid key')\n        if source_key not in self.nodes:\n            self.add_node(source_key)\n        if dest_key not in self.nodes:\n            self.add_node(dest_key)\n        self.nodes[source_key].add_neighbor(self.nodes[dest_key], weight)\n\n    def add_undirected_edge(self, src_key, dst_key, weight=0):\n        if src_key is None or dst_key is None:\n            raise TypeError('key cannot be None')\n        self.add_edge(src_key, dst_key, weight)\n        self.add_edge(dst_key, src_key, weight)\n","sourceCodeStart":39,"sourceCodeEnd":69,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/graphs_trees/graph/graph.py#L39-L69","documentation":"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.","triggerScenarios":"Calling add_edge(None, 'b') or add_edge('a', None); indirectly via add_undirected_edge with a None endpoint.","commonSituations":"Building edge lists from data with missing endpoints; None leaking from parsing/config into edge tuples.","solutions":["Filter edge tuples containing None endpoints before calling add_edge","Fix the upstream source of the None key (parser, config, join miss)","Validate edges in a loop: if src is not None and dst is not None: add_edge(...)"],"exampleFix":"# before\nfor src, dst in edges:\n    graph.add_edge(src, dst)  # KeyError on None\n\n# after\nfor src, dst in edges:\n    if src is not None and dst is not None:\n        graph.add_edge(src, dst)","handlingStrategy":"validation","validationCode":"if source_key is not None and dest_key is not None:\n    graph.add_edge(source_key, dest_key)","typeGuard":"def valid_edge_keys(src, dst) -> bool:\n    return src is not None and dst is not None","tryCatchPattern":"try:\n    graph.add_edge(src, dst)\nexcept KeyError as e:\n    if 'Invalid key' in str(e):\n        skip_or_log()\n    else:\n        raise","preventionTips":["Filter malformed edge tuples at load time","Validate endpoint keys in one pass before graph construction"],"tags":["graph","edge","keyerror","validation"],"backgroundTag":"invalid-key-argument","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}