Skip to content

assert.deepStrictEqual / util.isDeepStrictEqual throw TypeError on Maps with null keys #64433

Description

@XyraSinclair

Version

v24.13.1, v26.4.0 (reproduced on both)

Platform

Darwin 24.x arm64 (also reproduces on Linux x64)

Subsystem

assert, util

What steps will reproduce the bug?

const { isDeepStrictEqual } = require('node:util');

isDeepStrictEqual(
  new Map([[null, { v: 1 }], [{ a: 1 }, 1]]),
  new Map([[{ b: 2 }, { v: 1 }], [{ a: 1 }, 1]])
);
// TypeError: Cannot read properties of null (reading 'constructor')

The same input crashes assert.deepStrictEqual and assert.notDeepStrictEqual
with the same TypeError (instead of an AssertionError / clean pass).

The triggering shape: one Map has a null key whose value is an object, the
other Map lacks a null key but contains an object key with a deeply-equal
value, plus at least one additional entry. Simpler null-key cases (primitive
values, or no other entries) return correctly, so the crash is in the
second-pass unordered key matching.

How often does it reproduce? Is there a required condition?

Deterministic.

What is the expected behavior? Why is that the expected behavior?

isDeepStrictEqual returns false; assert.deepStrictEqual throws
AssertionError; assert.notDeepStrictEqual passes. A comparison predicate
should never throw a TypeError on valid inputs.

What do you see instead?

TypeError: Cannot read properties of null (reading 'constructor')

Additional information

Likely cause: in the fallback pass that pairs non-identical Map keys by deep
equality, keys with typeof key === 'object' are collected for pairwise
comparison, and null (also typeof 'object') reaches a code path that reads
key.constructor without a null guard.

Found by differential fuzzing of deep-equality implementations; happy to
provide more failing inputs (they all share the shape above).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions