### Version v22.16.0+ (and v24.x) ### Platform All platforms ### Subsystem assert ### What steps will reproduce the bug? ```javascript const assert = require('assert'); assert.deepEqual([null], [undefined]); ``` ### How often does it reproduce? Is there a required condition? Always reproduces on Node >= 22.16.0. Passes on Node <= 22.15.0. ### What is the expected behavior? Why is that the expected behavior? The assertion should **pass** because: 1. The [documentation](https://nodejs.org/api/assert.html#assertdeepequalactual-expected-message) states: "Primitive values are compared with the `==` operator" 2. In JavaScript, `null == undefined` is `true` 3. This worked in all Node versions prior to 22.16.0 ### What do you see instead? ``` AssertionError [ERR_ASSERTION]: Expected values to be loosely deep-equal: [ null ] should loosely deep-equal [ undefined ] ``` ### Root Cause PR #57619 (labeled as "performance improvement") introduced this change. The modification in [`objEquiv`](https://github.com/nodejs/node/pull/57619/files#diff-2da3538f1eacd02ed1b3c8f7fe3f8c0cee640295830a6f0dd4a6205326578958R785-R793) now checks `a[i] !== undefined` with **strict equality** (`===`) before calling `innerDeepEqual`, which would have used loose equality (`==`): ```javascript // Before: called innerDeepEqual() which respects loose equality mode if (!innerDeepEqual(a[i], b[i], mode, memos)) { return false; } // After: checks with strict equality BEFORE calling innerDeepEqual if (b[i] === undefined) { if (a[i] !== undefined || !hasOwn(a, i)) // <-- uses === not == return false; } ``` When comparing `[null]` vs `[undefined]`: - `b[0]` is `undefined` → enters first branch - `a[0] !== undefined` → `null !== undefined` is `true` (strict equality) - Returns `false` immediately, never calls `innerDeepEqual` which would use `==` ### Additional information - This is an **undocumented breaking change** in an LTS release - The PR was not labeled as semver-major - Affects anyone comparing arrays that may contain `null` values against expected `undefined` values (common with MongoDB/BSON which stores `undefined` as `null`) I understand `deepEqual` is marked as "Legacy" and docs warn it "can have surprising results", but this specific change contradicts the documented behavior and broke existing code without notice.