wavetermdev/waveterm · error

Invalid direction: ${direction}

Error message

Invalid direction: ${direction}

What it means

computeMoveNode translates a keyboard/mouse move direction (left/right/up/down/swap etc.) into a MoveNodeOperation. A direction value that reaches the switch's default branch has no mapping, so the function throws rather than silently ignoring the move.

Source

Thrown at frontend/layout/lib/layoutTree.ts:216

                        index: indexInParent() + 1,
                        node: nodeToMove,
                    };
            }
            break;
        case DropDirection.Center:
            if (nodeId !== rootNode.id && nodeToMoveId !== rootNode.id) {
                const swapAction: LayoutTreeSwapNodeAction = {
                    type: LayoutTreeActionType.Swap,
                    node1Id: nodeId,
                    node2Id: nodeToMoveId,
                };
                return swapAction;
            } else {
                console.warn("cannot swap");
            }
            break;
        default:
            throw new Error(`Invalid direction: ${direction}`);
    }

    if (
        newMoveOperation?.parentId !== nodeToMoveParent()?.id ||
        (newMoveOperation.index !== nodeToMoveIndexInParent() &&
            newMoveOperation.index !== nodeToMoveIndexInParent() + 1)
    )
        return {
            type: LayoutTreeActionType.Move,
            ...newMoveOperation,
        } as LayoutTreeMoveNodeAction;
}

export function moveNode(layoutState: LayoutTreeState, action: LayoutTreeMoveNodeAction) {
    console.log("moveNode", layoutState, action);
    const rootNode = layoutState.rootNode;
    if (!action) {
        console.error("no move node action provided");

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check which direction value triggered it and add a case for it in computeMoveNode's switch
  2. Fix the caller/keybinding sending an invalid direction literal
  3. Guard the call site with a whitelist check before dispatching the move action

Example fix

// before
moveNode(direction as Direction);

// after
const VALID = ["left", "right", "up", "down", "swap"];
if (VALID.includes(direction)) moveNode(direction);
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ["left", "right", "up", "down", "swap"] as const;
type Dir = typeof VALID[number];
if (!VALID.includes(direction as Dir)) return; // ignore invalid move

Type guard

function isMoveDirection(d: string): d is "left"|"right"|"up"|"down"|"swap" {
    return ["left","right","up","down","swap"].includes(d);
}

Try / catch

try {
    computeMoveNode(tree, direction);
} catch (e) {
    if (String(e.message).startsWith("Invalid direction")) {
        console.warn("unhandled move direction:", e.message);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling moveNode/computeMoveNode with a direction string not covered by the switch cases (e.g. an unknown literal, undefined due to a bad event mapping).

Common situations: New direction enum value added to the UI but not handled in layoutTree.ts; keybinding sends an unhandled direction; stale serialized pendingAction with an obsolete direction value.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/37f61c50e2f17825. Report an issue: GitHub.