Node tree getting corrupted (Vaadin 23 Flow)

We’re seeing some issues where our UI stops working properly (e.g. menus don’t work, popups don’t pop, etc). The onset of this behavior seems to be correlated with server side logs of this:

java.lang.IllegalStateException: Can't move a node from one state tree to another. If this is intentional, first remove the node from its current state tree by calling removeFromTree at com.vaadin.flow.internal.StateNode.doSetTree(StateNode.java:750) ~[flow-server-23.3.22.jar:23.3.22] at com.vaadin.flow.internal.StateNode.lambda$setTree$3(StateNode.java:382) ~[flow-server-23.3.22.jar:23.3.22] at com.vaadin.flow.internal.StateNode.visitNodeTree(StateNode.java:699) ~[flow-server-23.3.22.jar:23.3.22] at com.vaadin.flow.internal.StateNode.setTree(StateNode.java:382) ~[flow-server-23.3.22.jar:23.3.22] at com.vaadin.flow.internal.StateNode.setParent(StateNode.java:276) ~[flow-server-23.3.22.jar:23.3.22]

And then java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Unregistered node was not found based on its id. The tree is most likely corrupted.

at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:?]
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191) ~[?:?]
at com.vaadin.flow.server.FutureAccess.get(FutureAccess.java:62) [flow-server-23.3.22.jar:23.3.22]
at com.vaadin.flow.server.VaadinService.runPendingAccessTasks(VaadinService.java:2058) [flow-server-23.3.22.jar:23.3.22]
at com.vaadin.flow.server.VaadinSession.unlock(VaadinSession.java:712) [flow-server-23.3.22.jar:23.3.22]
at com.vaadin.flow.server.VaadinService.ensureAccessQueuePurged(VaadinService.java:2021) [flow-server-23.3.22.jar:23.3.22]

I’m at a loss how to debug this. Suggestions?

This can happen for example if you have a static references to a UI components and use it in different UI
Or, in spring project, using a injecting UI components with a wrong scope

statics aren’t going to be the cause, but we replaced some of our spring injection. Any suggestions how to find out what’s getting injected into the wrong place? I’m thinking that at least if I could see which components/nodes were involved, it would help identifiy the issue.

Okay - I’ve figured out a way to reliably trigger the issue locally is to use web browser refresh and I’m confused.
Historically these components are still currently UIScoped, but it seems like vaadin is trying to treat something as though we were using @PreserveOnRefresh or something.

Maybe you can find the component that causes the issue with the debugger: Add clarifying information to the error message about moving nodes to another state tree · Issue #9376 · vaadin/flow · GitHub
There is a Pull request to improve the error message and give you more information about the component.

Do you use @PreserveOnRefresh?

I have had issues in the past with scoped routes with that annotation. I forget exactly what it was, but it may be related.