Skip to content

fix: handle null field values when pasting into empty PTE fields#2160

Closed
christianhg wants to merge 9 commits intomainfrom
fix/crx-1886-null-field-paste-error
Closed

fix: handle null field values when pasting into empty PTE fields#2160
christianhg wants to merge 9 commits intomainfrom
fix/crx-1886-null-field-paste-error

Conversation

@christianhg
Copy link
Member

Summary

Fixes the "Attempt to apply insert patch to non-array value" error that occurs when pasting content into a Portable Text field that has a null value.

Related issue: CRX-1886

Root Cause

The setIfMissing patch only checks for undefined, treating null as "present". When pasting into an empty PTE field:

  1. PTE generates setIfMissing([], []) to ensure the array exists
  2. setIfMissing sees null as "present" and does nothing
  3. The subsequent insert patch with an index-based path [0] fails because there's no array to insert into

Changes

Fix 1: slate-plugin.patches.ts:139

  • Changed the empty→non-empty transition from insert(previousValue, 'before', [0]) to set(previousValue, [])
  • This handles the transition atomically regardless of field state

Fix 2: operation-to-patches.ts:296-301

  • Changed insertNodePatch fallback from setIfMissing([], []) + insert([block], 'before', [0]) to atomic set([block], [])
  • This ensures block insertion works when the field is null, undefined, or []

Test plan

  • Editor unit tests pass (300 tests)
  • Patches unit tests pass (64 tests)
  • Added null-field-bug.test.ts demonstrating the bug and fix

🤖 Generated with Claude Code

This fixes the "Attempt to apply insert patch to non-array value" error
that occurs when pasting content into a Portable Text field that has a
null value (as opposed to undefined or []).

The root cause was that setIfMissing only checks for undefined, treating
null as "present". When the field is null, the subsequent insert patch
with an index-based path fails because there's no array to insert into.

Changes:
- slate-plugin.patches.ts: Use atomic set() instead of insert() for
  empty→non-empty transitions
- operation-to-patches.ts: Use atomic set() instead of setIfMissing +
  insert when inserting into an empty array

Fixes CRX-1886

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Jan 30, 2026

⚠️ No Changeset found

Latest commit: 069102e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Jan 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
portable-text-editor-documentation Ready Ready Preview, Comment Jan 30, 2026 1:09pm
portable-text-example-basic Ready Ready Preview, Comment Jan 30, 2026 1:09pm
portable-text-example-legacy Ready Ready Preview, Comment Jan 30, 2026 1:09pm
portable-text-playground Ready Ready Preview, Comment Jan 30, 2026 1:09pm

Request Review

Update test expectations in placeholder-block.test.tsx and
event.patch.test.tsx to use atomic `set` patches instead of
`insert(..., 'before', [0])` for empty→non-empty transitions.

This aligns with the fix for null field handling - using atomic
set ensures the operation works regardless of whether the field
value is null, undefined, or an empty array.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update test expectations in:
- event.block.set.test.tsx
- event.block.unset.test.tsx
- change-subject.test.tsx

All tests now expect atomic `set` patches instead of `insert(..., 'before', [0])`
for empty→non-empty transitions, aligning with the fix for null field handling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update test expectations in:
- event.patch.test.tsx (lines 212, 294, 424)
- event.delete.backward.test.tsx (line 96)
- event.delete.block.test.tsx (line 88)
- event.delete.forward.test.tsx (line 92)

All tests now expect atomic `set` patches instead of `insert(..., 'before', [0])`
for empty→non-empty transitions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- event.child.unset.test.tsx (line 384)
- event.insert.block.test.tsx (lines 451, 548)
- event.patches.test.tsx (both initial patch tests)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
christianhg and others added 2 commits January 30, 2026 13:06
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update two test expectations (lines 196 and 317) to expect atomic `set`
operations instead of `insert(..., 'before', [0])` for empty→non-empty
transitions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant