From 182ad25157aa34bf041da7d55c1ed6180e5db95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Tue, 22 Sep 2026 15:53:21 +0200 Subject: [PATCH] NodeRegistry: pin that reset never reuses an id `reset` clears the lookup maps and deliberately leaves `node_id` where it is, so a stale id fails closed with a miss instead of resolving to whatever registers next. Nothing asserted that, and it is the invariant every id-addressed tool call leans on across a navigation. --- src/NodeRegistry.zig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/NodeRegistry.zig b/src/NodeRegistry.zig index c48213d80..40f5a81fd 100644 --- a/src/NodeRegistry.zig +++ b/src/NodeRegistry.zig @@ -190,3 +190,21 @@ test "NodeRegistry: resetFrame" { try testing.expectEqual(rb, registry.lookup_by_id.get(rb.id).?); try testing.expectEqual(b_node, registry.lookup_by_node.get(b_node).?.dom); } + +test "NodeRegistry: reset never reuses an id" { + var registry = NodeRegistry.init(testing.allocator); + defer registry.deinit(); + + var page = try testing.pageTest("cdp/registry1.html", .{}); + defer page.close(); + + const frame = page.frame().?; + const dom_node = (try frame.window._document.querySelector(.wrap("#a1"), frame)).?.asNode(); + // The pool recycles the `Node` itself, so keep the id, not the pointer. + const first_id = (try registry.register(dom_node)).id; + + registry.reset(); + try testing.expectEqual(null, registry.lookup_by_id.get(first_id)); + // A stale id stays a miss rather than resolving to whatever registers next. + try testing.expect((try registry.register(dom_node)).id != first_id); +}