From 76b0d1c8de720c893ca4a376db8a3168f4767759 Mon Sep 17 00:00:00 2001 From: dev Date: Wed, 3 Jun 2026 03:35:52 +0200 Subject: [PATCH] words/engine: guard the mark-walk against undefined block slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `getActiveMarksForSelection` → `collectBlockText` switched on `block.type` without a null check. When a table cell (inside a column) momentarily held an undefined child slot, the walk threw `Cannot read properties of undefined (reading 'type')`. The throw propagated out of `insertBlockInColumn` → `applyHistoryCommand` uncaught, aborting the command and leaving the editor unable to edit anything (and the column "add block" silently failing). Add an `if (!block) return` guard at the top of `collectBlockText` so a partial slot is skipped instead of crashing the whole command. Surfaced via the Chrome console (TypeError in selection-walkers.ts ← insert-block-types.ts:309). Engine tests 42/42 pass; selection-walkers type-checks clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../words/engine/operations/selection-walkers.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/uix/soma/components/words/engine/operations/selection-walkers.ts b/src/uix/soma/components/words/engine/operations/selection-walkers.ts index d617897a3..30cf47061 100644 --- a/src/uix/soma/components/words/engine/operations/selection-walkers.ts +++ b/src/uix/soma/components/words/engine/operations/selection-walkers.ts @@ -67,10 +67,15 @@ export function getTextEntries(doc: WordsDocument): readonly WordsTextEntry[] { } function collectBlockText( - block: WordsDocument['children'][number], + block: WordsDocument['children'][number] | undefined, path: WordsPath, out: WordsTextEntry[] ): void { + // Robustness: a cell / column / callout child slot can momentarily be + // undefined during an editing transition. Skip it rather than throwing + // from the mark-walk — an uncaught error here aborts the command and + // leaves the editor unable to edit at all. + if (!block) return; switch (block.type) { case 'paragraph': case 'heading':