Skip to content

Bug: calculateNewIndentation crashes — Cannot destructure property 'indent' of getResolvedParagraphProperties(node) as it is undefined #3208

@shri-scale

Description

@shri-scale

Summary

TypeError: Cannot destructure property 'indent' of 'getResolvedParagraphProperties(node)' as it is undefined. thrown from calculateNewIndentation whenever the indent toolbar commands run against a paragraph whose properties haven't been cached yet.

Reproduction

  1. Load a docx into a SuperDocEditor.
  2. Click into a paragraph that hasn't been visited by the layout/measurement pass yet (e.g. immediately after load, or a freshly-inserted paragraph).
  3. Click the toolbar's Increase Indent (or Decrease Indent) button.
  4. Crash.

Affects all four exported commands in packages/super-editor/src/editors/v1/core/commands/textIndent.js:
increaseTextIndent, decreaseTextIndent, setTextIndentation, unsetTextIndentation — all flow through calculateNewIndentation via modifyIndentation.

Root cause

packages/super-editor/src/editors/v1/core/commands/textIndent.js, in calculateNewIndentation:

function calculateNewIndentation(node, delta) {
  let { indent } = getResolvedParagraphProperties(node);   // ← unguarded
  let { left } = indent || {};
  ...
}

getResolvedParagraphProperties is a pure WeakMap.get(node) lookup against resolvedParagraphPropertiesCache. Cache misses return undefined, and destructuring { indent } from undefined throws.

The four other callers of getResolvedParagraphProperties in the codebase all guard the result — either with optional chaining (?.numberingProperties) or with the || calculateResolvedParagraphProperties(...) fallback used in resolveRunProperties and getInlineRunProperties. Only calculateNewIndentation is unguarded.

This is the same shape as #2896 (which fixed listRendering destructure in ParagraphNodeView) — a sibling case in textIndent.js was missed.

Suggested fix

One-line:

let { indent } = getResolvedParagraphProperties(node) ?? {};

Or, to mirror the other callers and actually compute on miss:

const props =
  getResolvedParagraphProperties(node) ||
  calculateResolvedParagraphProperties(editor, node, $pos);
let { indent } = props;

(The latter would require threading editor and $pos into calculateNewIndentation.)

Environment

  • superdoc@1.32.0
  • @superdoc-dev/react@1.3.0
  • React 19.2 / Next.js 16

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions