When a user moves an image node into a frame (artboard) or repositions it within one, the image permanently disappears for all other connected peers. The issue does not reproduce with the new renderer.
Root cause
The legacy reconciler treats a container change (reparent) as a removeChild + createInstance cycle, which triggers onDestroy on the image handler for every remote peer.
onDestroy clears the in-memory image cache (imageSource, imageState, imageFallback, imageTryoutAttempts) unless the local Konva attribute onMoveContainer is set. That flag is set by moveNodeToContainer (sdk.js ~line 17683) on the initiating peer only — it is never serialised to CRDT state and therefore never present on remote peers.
The subsequent onRender call starts an async loadImage. If a second move arrives before the fetch completes, onDestroy runs again on the now-empty cache, and the following onUpdate — which does not call loadImage — never retries. The image is then permanently invisible for those peers.
Affected call chain (legacy reconciler):
CRDT update received
→ reconciler removeChild → handler.onDestroy (clears cache, no onMoveContainer flag)
→ reconciler createInstance → handler.onRender (cache empty → async loadImage)
[second move arrives before loadImage completes]
→ reconciler removeChild → handler.onDestroy (clears again)
→ reconciler commitUpdate → handler.onUpdate (does NOT call loadImage → image lost)
Steps to reproduce
- Open a moodboard with two browser sessions (two different users).
- Add any existing image to the canvas.
- From session A, drag the image into a frame.
- From session A, move the image again within the frame (or drag it to another position).
- Observe session B — the image is invisible.
Reproduces consistently with the legacy reconciler. Does not reproduce with the new renderer.
Expected behaviour
The image remains visible for all peers regardless of how many times it is repositioned within or across frames.
Actual behaviour
The image disappears for all peers except the one performing the move.
When a user moves an image node into a frame (artboard) or repositions it within one, the image permanently disappears for all other connected peers. The issue does not reproduce with the new renderer.
Root cause
The legacy reconciler treats a container change (reparent) as a
removeChild+createInstancecycle, which triggersonDestroyon the image handler for every remote peer.onDestroyclears the in-memory image cache (imageSource,imageState,imageFallback,imageTryoutAttempts) unless the local Konva attributeonMoveContaineris set. That flag is set bymoveNodeToContainer(sdk.js ~line 17683) on the initiating peer only — it is never serialised to CRDT state and therefore never present on remote peers.The subsequent
onRendercall starts an asyncloadImage. If a second move arrives before the fetch completes,onDestroyruns again on the now-empty cache, and the followingonUpdate— which does not callloadImage— never retries. The image is then permanently invisible for those peers.Affected call chain (legacy reconciler):
Steps to reproduce
Reproduces consistently with the legacy reconciler. Does not reproduce with the new renderer.
Expected behaviour
The image remains visible for all peers regardless of how many times it is repositioned within or across frames.
Actual behaviour
The image disappears for all peers except the one performing the move.