Skip to content

fix: handle null in isJSONSerializable to prevent TypeError#574

Open
Zelys-DFKH wants to merge 2 commits into
unjs:mainfrom
Zelys-DFKH:fix/null-serializable
Open

fix: handle null in isJSONSerializable to prevent TypeError#574
Zelys-DFKH wants to merge 2 commits into
unjs:mainfrom
Zelys-DFKH:fix/null-serializable

Conversation

@Zelys-DFKH
Copy link
Copy Markdown

@Zelys-DFKH Zelys-DFKH commented May 8, 2026

Fixes #571isJSONSerializable crashes with TypeError when passed null.

Root cause:

  • Line 22 checks t === null instead of value === null
  • Since typeof null === "object" (JavaScript quirk), this condition never matches (dead code)
  • Execution reaches line 28: if (value.buffer) → crashes on null

Solution:

  • Add explicit null check in early return alongside undefined
  • Remove unreachable t === null condition (typeof always returns a string, never "null")

Changes:

  • src/utils.ts: 2-line fix (add null guard, remove dead condition)
  • test/index.test.ts: 6 regression tests covering null, undefined, primitives, objects, special cases

Test results: 34/34 passing ✅

  • All 28 existing tests pass
  • All 6 new regression tests pass (including null crash case)

Summary by CodeRabbit

  • Bug Fixes

    • Treat null and undefined as non-serializable in validation, preventing them from being accepted as valid serialized values.
  • Tests

    • Added comprehensive test coverage for serialization validation across primitives, plain objects/arrays, typed arrays, binary buffers, and form-encoded data.

Fixes unjs#571 - isJSONSerializable crashed when passed null because:
1. Line 22 checked 't === null' instead of 'value === null'
2. typeof null is 'object', so the dead code check never triggered
3. Line 28 then accessed value.buffer on null, throwing TypeError

Solution: Add explicit null guard in early return, alongside undefined check.
Also removed incorrect 't === null' condition since typeof returns string.

Added regression tests for null, undefined, and other edge cases.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f506ee81-da28-47e0-82f5-a2804a274998

📥 Commits

Reviewing files that changed from the base of the PR and between 93f1cde and 852f41f.

📒 Files selected for processing (1)
  • test/index.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/index.test.ts

📝 Walkthrough

Walkthrough

The PR makes isJSONSerializable return false for both undefined and null and adds a Vitest suite verifying behavior for null, undefined, primitives, plain objects/arrays, Uint8Array/ArrayBuffer, FormData, and URLSearchParams.

Changes

isJSONSerializable Bug Fix

Layer / File(s) Summary
Core Logic Fix
src/utils.ts
Function now returns false for both undefined and null in the initial guard clause, preventing null dereference in later type checks.
Test Coverage
test/index.test.ts
New isJSONSerializable test suite verifies expected return values for null, undefined, primitives, plain objects/arrays, Uint8Array/ArrayBuffer, FormData, and URLSearchParams.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A rabbit nudged a null aside,
"No crash today," it sweetly cried.
With tests in place and guards that sing,
Our JSON checker hops on spring.
✨🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: handling null in isJSONSerializable to prevent TypeError, which matches the primary change in the changeset.
Linked Issues check ✅ Passed The PR fully addresses all coding requirements from issue #571: fixes the incorrect null check, ensures null is treated as JSON-serializable, prevents property access on null, and adds comprehensive regression tests.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the null handling bug in isJSONSerializable; no unrelated modifications are present in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/index.test.ts`:
- Around line 558-561: The test description is misleading because ArrayBuffer
doesn't have a .buffer property and so the isJSONSerializable branch checking
value.buffer isn't exercised; update the test(s) so one explicitly uses a
TypedArray (e.g., new Uint8Array(10)) to hit the value.buffer branch and assert
isJSONSerializable(...) === false, and either rename the existing ArrayBuffer
test to reflect "returns false for ArrayBuffer" or split into two tests: one for
TypedArray (exercises value.buffer) and one for ArrayBuffer (verifies
non-serializable via constructor check) while keeping references to the
isJSONSerializable function in the test names for clarity.
- Line 538: Add the same ESLint suppression used elsewhere for null to the
failing assertion: before the expect(isJSONSerializable(null)) call add an
inline comment to disable the unicorn/no-null rule for the next line so CI won't
fail; locate the expect call referencing isJSONSerializable and add the same "//
eslint-disable-next-line unicorn/no-null" style suppression used at lines 58 and
208.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6e89410c-737a-4086-b1cf-7a91ad5029ca

📥 Commits

Reviewing files that changed from the base of the PR and between dfbe3ca and 93f1cde.

📒 Files selected for processing (2)
  • src/utils.ts
  • test/index.test.ts

Comment thread test/index.test.ts Outdated
Comment thread test/index.test.ts Outdated
- Add ESLint suppression for null in isJSONSerializable test (line 538)
- Split misleading ArrayBuffer test into two tests:
  - TypedArray test that exercises the .buffer property check
  - ArrayBuffer test that verifies non-serializable via constructor check

Fixes CodeRabbit comments on PR unjs#574.
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.

isJSONSerializable bug

1 participant