Frontmatter
| id | 8595 |
| title | Investigate TreeList Chimera VDOM Corruption (Handover) |
| state | Closed |
| labels | bugai |
| assignees | tobiu |
| createdAt | Jan 13, 2026, 1:47 PM |
| updatedAt | Jan 13, 2026, 2:08 PM |
| githubUrl | https://github.com/neomjs/neo/issues/8595 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | null |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Jan 13, 2026, 2:08 PM |
Investigate TreeList Chimera VDOM Corruption (Handover)
tobiu assigned to @tobiu on Jan 13, 2026, 1:47 PM

tobiu
Jan 13, 2026, 2:07 PM
Input from Gemini 3 Pro:
✦ I have identified and fixed the root cause of the "Chimera" VDOM corruption.
Root Cause Analysis: The
ULcontainer used to group child items inNeo.tree.Listwas created without an explicit ID. This made it vulnerable during rapid state changes (e.g., expanding a folder while scrolling/loading).
- When a folder expands, the
ULtransitions fromremoveDom: true(hidden/filtered out) toremoveDom: false(visible).- In a race condition, the App Worker VDOM reflects the new state (visible
UL), but an incoming VNode update from the VDOM Worker (based on the previous hidden state) aligns theULin the local VDOM with the nextLIin the incoming VNode.Neo.util.VDom.syncVdomStateattempts to sync IDs. Since theULhad no ID, and the alignedLInode did, the utility erroneously copied theLI's ID onto theUL.- This resulted in a "Chimera" node: a
ULtag bearing the ID of a siblingLI, causing stylesheets and logic to misidentify the container as an item.Fix: I have modified
src/tree/List.mjsto assign a deterministic ID (parentId + '__ul') to every child containerUL. This preventssyncVdomStatefrom overwriting the ID during misalignment, effectively creating a shield against this class of race condition.Verification:
- Added a new test case in
test/playwright/unit/tree/ListRaceCondition.spec.mjsverifying thatULcontainers now possess the correct, deterministic IDs.- Confirmed that standard expansion tests still pass.
The fix has been pushed to
dev.
tobiu closed this issue on Jan 13, 2026, 2:08 PM
tobiu cross-referenced by #8596 on Jan 13, 2026, 2:11 PM
Current State:
expandParents), horizontal scrolling (addedinline: 'start'), header bold styling (SCSS),getListItemsRootrobustness.LIappears to merge with its childrenUL(theULacquires theLI's ID and styles, causing layout breakage).TreeList.spec.mjs,TreeListRaceTest.spec.mjs) confirm that standard expansion and store-update race conditions do not reproduce the Chimera structure in isolation.Hypothesis: The issue likely involves complex VDOM patching interactions or race conditions not yet simulated in unit tests, possibly involving
waitForDomRecttiming or multiple interleaved updates in the real App Worker environment.Next Steps for Investigation:
Neo.currentWorker.promiseMessageorupdate()insrc/tree/List.mjsto log the exact VDOM structure being sent to the VDOM worker during the expansion sequence.inspect_component_render_tree) in the next session to inspect the live application state when the bug occurs.vdom.HelperorDomApipatching logic for specific edge cases involving sibling tag changes or ID reuse (though improbable).