{"record":{"id":"657b486cc409580d","repo":"donnemartin/interactive-coding-challenges","slug":"key-cannot-be-none","errorCode":null,"errorMessage":"key cannot be None","messagePattern":"key cannot be None","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"graphs_trees/graph/graph.py","lineNumber":50,"sourceCode":"\n    def remove_neighbor(self, neighbor):\n        if neighbor is None:\n            raise TypeError('neighbor cannot be None')\n        if neighbor.key not in self.adj_nodes:\n            raise KeyError('neighbor not found')\n        neighbor.incoming_edges -= 1\n        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)","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/graphs_trees/graph/graph.py#L32-L68","documentation":"Raised by Graph.add_node when key is None. Node keys index the graph's nodes dict and drive all lookups (BFS, DFS, shortest path), so None keys are rejected outright. This is a defensive TypeError against malformed graph definitions.","triggerScenarios":"Calling graph.add_node(None); passing a None key derived from data into add_node, add_edge, or add_undirected_edge.","commonSituations":"Building graphs from records with missing ID fields; a key computed as data.get('id') returning None; refactor changing key type to Optional.","solutions":["Validate/skip records with missing keys before graph construction","Default None keys to a generated unique key (e.g. uuid or counter)","Assert key is not None in a wrapper around graph building code"],"exampleFix":"# before\ngraph.add_node(record.get('id'))\n\n# after\nkey = record.get('id')\nif key is not None:\n    graph.add_node(key)","handlingStrategy":"validation","validationCode":"if key is not None:\n    graph.add_node(key)","typeGuard":"def valid_key(key) -> bool:\n    return key is not None","tryCatchPattern":"try:\n    graph.add_node(key)\nexcept TypeError:\n    log.warning('skipping node with missing key: %r', key)","preventionTips":["Validate record IDs before building graphs","Generate unique keys for records with missing identifiers"],"tags":["graph","node-key","none-check","typeerror"],"backgroundTag":"none-argument-rejected","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}