{"record":{"id":"53629f3a16e7ae94","repo":"donnemartin/interactive-coding-challenges","slug":"neighbor-not-found-53629f","errorCode":null,"errorMessage":"neighbor not found","messagePattern":"neighbor not found","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"graphs_trees/graph/graph_solution.ipynb","lineNumber":205,"sourceCode":"    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.key)\\n\",\n    \"\\n\",\n    \"    def __lt__(self, other):\\n\",\n    \"        return self.key < other.key\\n\",\n    \"\\n\",\n    \"    def add_neighbor(self, neighbor, weight=0):\\n\",\n    \"        if neighbor is None or weight is None:\\n\",\n    \"            raise TypeError('neighbor or weight cannot be None')\\n\",\n    \"        neighbor.incoming_edges += 1\\n\",\n    \"        self.adj_weights[neighbor.key] = weight\\n\",\n    \"        self.adj_nodes[neighbor.key] = neighbor\\n\",\n    \"\\n\",\n    \"    def remove_neighbor(self, neighbor):\\n\",\n    \"        if neighbor is None:\\n\",\n    \"            raise TypeError('neighbor cannot be None')\\n\",\n    \"        if neighbor.key not in self.adj_nodes:\\n\",\n    \"            raise KeyError('neighbor not found')\\n\",\n    \"        neighbor.incoming_edges -= 1\\n\",\n    \"        del self.adj_weights[neighbor.key]\\n\",\n    \"        del self.adj_nodes[neighbor.key]\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Graph:\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.nodes = {}  # Key = key, val = Node\\n\",\n    \"\\n\",\n    \"    def add_node(self, key):\\n\",\n    \"        if key is None:\\n\",\n    \"            raise TypeError('key cannot be None')\\n\",\n    \"        if key not in self.nodes:\\n\",\n    \"            self.nodes[key] = Node(key)\\n\",\n    \"        return self.nodes[key]\\n\",\n    \"\\n\",\n    \"    def add_edge(self, source_key, dest_key, weight=0):\\n\",","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/graphs_trees/graph/graph_solution.ipynb#L187-L223","documentation":"Raised by Node.remove_neighbor(neighbor) when neighbor.key is not present in self.adj_nodes, meaning no edge from this node to that neighbor exists. Because the method deletes from both adj_weights and adj_nodes, removing a non-existent adjacency would corrupt the dicts, so it fails fast with KeyError.","triggerScenarios":"Calling remove_neighbor for a node never passed to add_neighbor/add_edge; removing an undirected edge by calling remove_neighbor on only one side (or the wrong side); double-removal of the same edge.","commonSituations":"Graph teardown code assuming symmetric adjacency; replaying edge-removal logs where some edges were already applied; desync between adj_weights and adj_nodes after partial manual mutation.","solutions":["Guard the call: check neighbor.key in node.adj_nodes before removing","For undirected graphs, remove from both endpoints' adj lists exactly once, in the correct order","Track edge existence in one place (e.g., a set of (src,dst) tuples) instead of manually managing both directions"],"exampleFix":"# before\nnode.remove_neighbor(other)  # KeyError: neighbor not found\n\n# after\nif other.key in node.adj_nodes:\n    node.remove_neighbor(other)","handlingStrategy":"validation","validationCode":"if neighbor is not None and neighbor.key in node.adj_nodes:\n    node.remove_neighbor(neighbor)","typeGuard":"def edge_exists(node, neighbor):\n    return neighbor is not None and neighbor.key in node.adj_nodes","tryCatchPattern":"try:\n    node.remove_neighbor(neighbor)\nexcept KeyError:\n    pass  # edge absent; treat as no-op or log","preventionTips":["Check membership before every remove_neighbor call","For undirected graphs, remove from both endpoints exactly once"],"tags":["python","graph","keyerror","edge-removal"],"backgroundTag":"key-not-found","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}