fix(repository): dedupe/filter source ids before querying in hasManyThrough, hasMany, and hasOne inclusion resolvers - #11784
Open
karthikchundi-commits wants to merge 2 commits into
Conversation
4 tasks
dhmlau
approved these changes
Sep 15, 2026
Contributor
|
Hi, @karthikchundi-commits. Thanks for the PR. Everything seems good. Just one small piece of feedback I'd like to give is that the comments in the code are too descriptive. Can we make them concise and leave the detailed explanation here in the PR description? |
…hrough inclusion resolver
hasManyThrough's inclusion resolver passed its raw, unfiltered
sourceIds array by reference straight into findByForeignKeys(), which
wraps it in an {inq: [...]} where clause and hands that same array to
the connector without cloning it first. A connector/query layer that
sanitizes an inq array in place (e.g. stripping falsy values before
running the query, as the in-memory connector does) then mutates that
exact array out from under the caller - shrinking the very sourceIds
array the resolver still needs below, unmodified, to correctly zip
through-results back onto each original entity via
flattenTargetsOfOneToManyRelation(). That silently misaligns or
truncates the returned array whenever any source entity's key was
undefined (e.g. excluded by a fields filter) or duplicated another
entity's.
belongsTo and referencesMany inclusion resolvers already pass a fresh,
deduplicated, filtered array (never the original reference) before
querying; hasManyThrough had no dedup/filter attempt at all.
Added a regression test to has-many-through-inclusion-resolver.acceptance.ts:
a duplicate source entity plus one with an undefined key, confirming
the result stays length-3 and aligned with the input. Verified the
test actually catches the bug by temporarily reverting the source fix
and re-running - reproduces the exact truncation (length 2 instead of
3) this fix addresses.
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Karth <karthik.chundi@gmail.com>
…and hasOne inclusion resolvers
Both resolvers had the same aliasing bug just fixed in hasManyThrough:
they passed their raw, unfiltered source-id array by reference
straight to findByForeignKeys(), which wraps it in an {inq: [...]}
where clause and hands that same array on to the connector. A
connector/query layer that sanitizes an inq array in place (e.g.
stripping falsy values before running the query, as the in-memory
connector does) then mutates that shared array out from under the
caller - shrinking the very array each resolver still needed,
unmodified, to zip results back onto each original entity. That
silently truncated and misaligned the resolver's return value whenever
any source entity's key was undefined (e.g. excluded by a fields
filter) or duplicated another entity's.
belongsTo and referencesMany already pass a fresh, deduplicated,
filtered array (never the original reference) before querying;
hasMany and hasOne now do the same.
Confirmed via a standalone script against the real compiled resolvers
and an in-memory DataSource: reverting just this fix reproduces the
truncated/misaligned result (length 2 instead of 3 for a 3-entity
batch with one undefined key); with the fix, the result is correctly
length 3 with undefined in the right position.
Includes a test fix for the same regression tests: toJSON() serializes
an undefined array element to null (JSON has no undefined), so the
memory-connector acceptance run must assert null, not undefined, for
that slot.
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Karth <karthik.chundi@gmail.com>
karthikchundi-commits
force-pushed
the
fix/has-many-through-source-id-mutation
branch
from
September 22, 2026 17:57
dcc05c8 to
b579d30
Compare
Author
|
@dhmlau Two things:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was originally scoped to
hasManyThroughonly. It now also absorbs thehasMany/hasOnefix from #11764, which was closed in favor of this PR but never actually landed here — consolidating both so the fix isn't lost.The bug
hasManyThrough,hasMany, andhasOne's inclusion resolvers each passed their raw, unfilteredsourceIdsarray by reference straight intofindByForeignKeys(), which wraps it in an{inq: [...]}where clause and hands that same array to the connector without cloning it first. A connector/query layer that sanitizes aninqarray in place (e.g. stripping falsy values before running the query, as the in-memory connector does) then mutates that exact array out from under the caller — shrinking the verysourceIdsarray each resolver still needs, unmodified, to correctly zip results back onto each original entity. That silently misaligns or truncates the returned array whenever any source entity's key was undefined (e.g. excluded by a fields filter) or duplicated another entity's.belongsToandreferencesManyinclusion resolvers already pass a fresh, deduplicated, filtered array (never the original reference) before querying.hasManyThroughhad no dedup/filter attempt at all;hasMany/hasOnedidn't either.Testing
Added a regression test to each of
has-many-through-inclusion-resolver.acceptance.ts,has-many-inclusion-resolver.relation.acceptance.ts, andhas-one.inclusion-resolver.acceptance.ts: a duplicate source entity plus one with an undefined key, confirming the result stays length-3 and aligned with the input. Verified each test actually catches the bug by temporarily reverting the corresponding source fix and re-running — reproduces the exact truncation (length 2 instead of 3) this fix addresses.128 passing, 8 pending (pre-existing, unrelated to this change), no failures.
Checklist
npm testpasses on your machine