Two separately created objects can have identical fields and still be different values for includes. Use the same reference for identity membership, or compare a documented stable key for record membership.
Reproduce the behavior safely
Run this self-contained fixture in an empty temporary directory, separate from your project. Shell examples create only named fixture files there. JavaScript examples use local values and send no network requests.
const assert = require('node:assert/strict');
const saved = {id: 'task-7', completed: false};
const rows = [saved];
const received = {id: 'task-7', completed: false};
assert.equal(rows.includes(saved), true);
assert.equal(rows.includes(received), false);
assert.equal(rows.some(row => row.id === received.id), true);
assert.equal(rows.some(row => row.id === 7), false);
console.log('same reference found; equivalent record matched by string id');Observed local output
same reference found; equivalent record matched by string idWhy the result changes
A database read, JSON parse or object spread can produce another object reference. The fixture shows why inspecting a console display of fields does not prove reference equality. Matching id answers a business question about records; it does not establish that every field is equal. The final check also makes the identifier type visible instead of silently coercing unrelated representations.
Choose and verify the correction
Choose the definition of a match before changing the code. For stable record IDs, validate presence and type, then use some for a boolean answer or find when you need the existing record. For compound identity, compare the required fields explicitly. If repeated lookup dominates, maintain an index under the same key contract and update it when records change. Define how duplicate or missing IDs are handled.
Limits and next checks
The fixture uses plain objects and string identifiers. Database-specific identifier objects may require a documented equality method or a canonical representation; do not assume this exact predicate covers them. JSON string comparison is not a general deep-equality definition and can conceal omitted fields. This guide concerns reference versus record identity, rather than invalid-number membership.
Related: Object Spread Still Mutates Nested State: Copy Each Changed Level.
Isolated fixture executed on macOS on November 10, 2026 (KST), with v26.5.0. The observed output verifies this example, not every application or runtime.