Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code 661e6596b5 Delete record crashes when cached ONE_TO_MANY relation value is null
https://sonarly.com/issue/10239?type=bug

Deleting a record on a custom object crashes with "null is not an object (evaluating 'n.map')" because `getRecordNodeFromRecord` passes null relation values to `getRecordConnectionFromRecords` without a null check.

Fix: Added `!Array.isArray(value)` null guards in two locations in `getRecordNodeFromRecord.ts`, restoring the runtime safety check that was removed in commit `a7fcc5d47ec`:

1. **Line 76-78 (RELATION ONE_TO_MANY)**: Before passing `value` as `records` to `getRecordConnectionFromRecords`, we now check that `value` is actually an array. When the Apollo cache returns partial data (`returnPartialData: true`), ONE_TO_MANY relation fields can be `null` instead of an array. The guard returns `undefined`, which is filtered out by `.filter(isDefined)` downstream — the same pattern used by all other early-return guards in this function.

2. **Line 120-122 (MORPH_RELATION ONE_TO_MANY)**: The identical guard for the morph relation variant of ONE_TO_MANY, which had the same vulnerability.

This is the exact guard (`Array.isArray(value)`) that the original code used before it was replaced with a metadata-only type check in commit `a7fcc5d47ec`. The fix is minimal and matches the existing defensive patterns in the file.
2026-03-06 12:35:58 +00:00
@@ -73,6 +73,10 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
return undefined;
}
if (!Array.isArray(value)) {
return undefined;
}
return [
gqlField,
getRecordConnectionFromRecords({
@@ -113,6 +117,10 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
return undefined;
}
if (!Array.isArray(value)) {
return undefined;
}
return [
gqlField,
getRecordConnectionFromRecords({