Skip to content

fix: throw proper immer error when applyPatches path traverses null#1251

Merged
mweststrate merged 1 commit into
immerjs:mainfrom
JSap0914:fix/apply-patches-null-path-traversal
Jul 16, 2026
Merged

fix: throw proper immer error when applyPatches path traverses null#1251
mweststrate merged 1 commit into
immerjs:mainfrom
JSap0914:fix/apply-patches-null-path-traversal

Conversation

@JSap0914

Copy link
Copy Markdown
Contributor

Bug

applyPatches throws a native TypeError instead of immer's own error when a patch path navigates through a null intermediate value.

Root cause: isObjectish is implemented as typeof target === "object". Because typeof null === "object" in JavaScript, isObjectish(null) returns true. The guard inside applyPatches_ that is supposed to catch non-navigable intermediates therefore lets null slip through. The next iteration (or the post-loop getArchtype call) then does null[DRAFT_STATE] and crashes with:

TypeError: Cannot read properties of null (reading 'Symbol(immer-state)')

instead of immer error 18:

Cannot apply patch, path doesn't resolve: a/b

Fix

Add an explicit base === null check alongside !isObjectish(base) in the path-traversal loop of applyPatches_ (src/plugins/patches.ts):

-if (!isObjectish(base)) die(errorOffset + 2, path.join("/"))
+if (base === null || !isObjectish(base)) die(errorOffset + 2, path.join("/"))

Verification

yarn test:src
# Test Files  22 passed (22)
# Tests  3652 passed | 8 skipped (3660)

New test added in __tests__/patch.js:

  • applyPatches({a: null}, [{op: 'add', path: ['a', 'b'], value: 1}]) now throws with message "Cannot apply patch, path doesn't resolve: a/b"

This PR was prepared with AI assistance.

typeof null === "object" causes isObjectish(null) to return true,
silently bypassing the path-resolution guard inside applyPatches_.
Traversal then calls getArchtype(null) which accesses null[DRAFT_STATE]
and crashes with a native TypeError instead of immer error 18
("Cannot apply patch, path doesn't resolve").

Add an explicit null check alongside isObjectish so the guard fires
correctly and the caller receives the expected immer error message.

Fixes: applyPatches({a: null}, [{op: 'add', path: ['a', 'b'], value: 1}])
Copilot AI review requested due to automatic review settings June 17, 2026 11:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mweststrate

Copy link
Copy Markdown
Collaborator

great catch and fix, thanks!

@mweststrate mweststrate merged commit e38ad71 into immerjs:main Jul 16, 2026
1 check passed
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 11.1.14 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants