Skip to content

Fix Shift+Tab outdent failing with 'Sibling not found' error after rapid node creation #662

Description

@malibio

Overview

When users rapidly create nested nodes and then press Shift+Tab to outdent, the operation fails with "Sibling not found" error. The node visually jumps two levels up instead of one, and the UI becomes out of sync with the backend.

Problem Statement

User Experience:

  1. User creates a series of nested nodes (successfully)
  2. User creates a new node below a nested node
  3. User immediately presses Shift+Tab to outdent the new node
  4. Error appears: Sibling not found: <uuid>
  5. Node jumps two levels up visually (incorrect)
  6. Refresh required to restore correct UI state

Evidence:

[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (parent, line 0)
[Error] [outdentNode] Failed to move node, rolled back: – Error: Operation failed: Query failed: Sibling not found: aee71ba9-8ca2-4728-9920-e1f0f5d6e011 — backend-adapter.ts:335

Root Cause

Location: packages/desktop-app/src/lib/services/reactive-node-service.svelte.ts (line 871)

When outdenting, the frontend calls:

await sharedNodeStore.waitForNodeSaves([nodeId]);
moveNodeCommand(nodeId, newParentId, oldParentId);

The oldParentId is passed as insertAfterNodeId to tell the backend where to position the outdented node. However:

  1. We only wait for nodeId (the node being moved) to be persisted
  2. We don't wait for oldParentId (the "insert after" sibling)
  3. The backend queries for children of newParentId and looks for oldParentId among them
  4. If oldParentId hasn't been fully persisted with its parent edge yet, the backend fails with "Sibling not found"

Why it happens:

  • Rapid node creation causes a queue of pending saves
  • When outdenting immediately after creation, oldParentId may still be pending persistence
  • The backend can't find the sibling reference and fails

Proposed Solution

Wait for BOTH the node being moved AND the oldParentId to be fully persisted before calling moveNodeCommand:

// Before (broken):
await sharedNodeStore.waitForNodeSaves([nodeId]);

// After (fixed):
await sharedNodeStore.waitForNodeSaves([nodeId, oldParentId]);

Acceptance Criteria

  • Shift+Tab outdent succeeds after rapid node creation
  • No "Sibling not found" errors during normal outdent operations
  • Node moves only one level up (correct behavior)
  • UI stays in sync with backend after outdent
  • No new test failures
  • Code passes bun run quality:fix

Technical Specifications

Files to Modify

  • reactive-node-service.svelte.ts: packages/desktop-app/src/lib/services/reactive-node-service.svelte.ts (line 871)

Implementation Details

Change at line 871:

// CRITICAL: Wait for BOTH the node AND oldParentId to be persisted before moving
// The backend needs oldParentId to exist as a child of newParentId to find it as the "insert after" sibling.
await sharedNodeStore.waitForNodeSaves([nodeId, oldParentId]);

Related Backend Code

The error originates from:

  • packages/core/src/db/surreal_store.rs (line 2806)
  • Backend queries for has_child edges and expects to find oldParentId in the result

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfrontend

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions