Skip to content

throw instead of wrapping the 16-bit UID counter in Tree::getUID - #1244

Merged
facontidavide merged 1 commit into
BehaviorTree:masterfrom
aysha-afrah26:tree-uid-wraparound
Oct 24, 2026
Merged

facontidavide merged 1 commit into
BehaviorTree:masterfrom
aysha-afrah26:tree-uid-wraparound

Conversation

@aysha-afrah26

Copy link
Copy Markdown
Contributor

Tree::getUID() hands out node UIDs from a uint16_t counter, and the XML parser calls it once for every node it instantiates. Nothing stops the counter at 65535, so in a tree with more nodes it wraps to 0 and the following nodes get the same UID as the first ones. The node count comes straight from the tree XML, and SubTree expansion multiplies it, so a fairly small document can get there. Since the UID is the node identity for Groot2 (nodes_by_uid, the status buffer and the breakpoint/replace hooks), for FileLogger2, SqliteLogger and TreeObserver, and for the auto-generated path of unnamed nodes, aliased nodes end up sharing each other's hooks, transitions and statistics. I noticed it while building a Sequence with 65540 AlwaysSuccess children: five nodes came back with a UID that was already in use, and two of them even report the same fullPath(), AlwaysSuccess::2. Groot2 and the btlog format serialize the UID as 16 bits, so widening it isn't really an option, and getUID() now throws a RuntimeError once the counter is exhausted so tree creation fails with a clear message instead. Trees up to 65535 nodes behave exactly as before, there is no API or ABI change, and the new BehaviorTreeFactory.TooManyNodesForUID test fails on master and passes with the fix.

@facontidavide
facontidavide merged commit 7f0576b into BehaviorTree:master Oct 24, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants