toeverything/AFFiNE · error · BlockSuiteError

DatabaseBlockError

DatabaseBlockError

Error message

Unknown arrow keys, only support: up, down, left, and right keys.

What it means

KanbanSelectionController.getNextFocusCard (kanban/pc/controller/selection.ts:307-385) walks an if-chain over nextPosition ('up','down','left','right'); the trailing throw at :381 fires only when the caller passes a value outside that union. In well-typed TypeScript code it is unreachable; at runtime it appears when key names are forwarded un-narrowed (e.g. raw KeyboardEvent.key like 'ArrowUp') or via any-casts.

Solutions

  1. Map KeyboardEvent.key to the union ('ArrowUp'->'up', 'ArrowDown'->'down', 'ArrowLeft'->'left', 'ArrowRight'->'right') before calling
  2. Keep the parameter typed as the literal union and avoid any/string casts at event boundaries
  3. Early-return for unrecognized keys instead of forwarding them

Example fix

// before
controller.getNextFocusCard(selection, index, key as any); // key = 'ArrowUp' -> throws

// after
const map: Record<string, 'up'|'down'|'left'|'right'> = {
  ArrowUp: 'up', ArrowDown: 'down', ArrowLeft: 'left', ArrowRight: 'right',
};
const dir = map[key];
if (dir) controller.getNextFocusCard(selection, index, dir);
Defensive patterns

Strategy: type-guard

Validate before calling

const KEY_TO_DIRECTION: Record<string, 'up' | 'down' | 'left' | 'right'> = {
  ArrowUp: 'up',
  ArrowDown: 'down',
  ArrowLeft: 'left',
  ArrowRight: 'right',
};

const direction = KEY_TO_DIRECTION[event.key];
if (direction) {
  controller.getNextFocusCard(selection, index, direction);
}

Type guard

type Direction = 'up' | 'down' | 'left' | 'right';
const isDirection = (d: string): d is Direction =>
  d === 'up' || d === 'down' || d === 'left' || d === 'right';

Prevention

When it happens

Trigger: A custom hotkey/keyboard handler mapping KeyboardEvent.key directly to getNextFocusCard without translating 'ArrowUp' to 'up'; JS callers or string-cast code bypassing the 'up'|'down'|'left'|'right' literal-union type.

Common situations: Custom kanban keyboard navigation extensions; tests calling the private controller with arbitrary strings; refactors that widen the direction parameter to string.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/eecfe0d617dbccec. Report an issue: GitHub.

Appendix: source

Thrown at blocksuite/affine/data-view/src/view-presets/kanban/pc/controller/selection.ts:381

    if (nextPosition === 'right') {
      return getNextGroupFocusElement(
        this.host,
        groups,
        selection,
        groupIndex => (groupIndex === groups.length - 1 ? 0 : groupIndex + 1)
      );
    }

    if (nextPosition === 'left') {
      return getNextGroupFocusElement(
        this.host,
        groups,
        selection,
        groupIndex => (groupIndex === 0 ? groups.length - 1 : groupIndex - 1)
      );
    }
    throw new BlockSuiteError(
      ErrorCode.DatabaseBlockError,
      'Unknown arrow keys, only support: up, down, left, and right keys.'
    );
  }

  getNextFocusCell(
    selection: KanbanCellSelection,
    index: number,
    nextPosition: 'up' | 'down' | 'left' | 'right'
  ):
    | {
        cell: KanbanCell;
        cardId?: string;
        groupKey?: string;
      }
    | undefined {
    const host = this.host;
    if (!host) {

View on GitHub (pinned to b4c8548c09)