Skip to content

fix: do not re-apply the query for per-item patchMany/removeMany calls - #48

Merged
fratzinger merged 1 commit into
mainfrom
fix/change-many-query-not-reapplied
Sep 8, 2026
Merged

fratzinger merged 1 commit into
mainfrom
fix/change-many-query-not-reapplied

Conversation

@fratzinger

Copy link
Copy Markdown
Member

Problem

patchMany/removeMany fall back to one call per item when the service does not allow multi. In that fallback, params.query was forwarded to every patch(id, ...)/remove(id, ...) call (minus $limit/$skip/$sort).

But the query selects which items are affected and is already consumed by the find. Re-applying it per item is redundant at best - and harmful at worst: adapters apply params.query as an additional filter (_get/findOneAndUpdate with { ...query, [id]: id }), so an item that no longer matches between find and patch throws NotFound and takes the whole Promise.all down with it, after changes have partially been written. Custom query operators that only find hooks resolve run into the same wall. That $limit/$skip/$sort had to be filtered out by hand was the symptom.

Authorization is not an argument for keeping it: hook-based restrictions (e.g. limitToOwner) set their query again in the patch/remove hooks anyway, and a caller-supplied query was already enforced by the find.

Change

src/common/change-many.ts - blacklist → whitelist:

  • the per-item calls only get $select from the query, so both paths (multi vs. per-item) return the same shape. provider, user, authentication etc. are untouched.
  • the fallback find replaces $select with the id property - it only exists to collect the ids, so it no longer over-fetches and the id is always present.
  • $sort/$limit/$skip still shape the find.

Tests

Three new tests each for patchMany and removeMany:

  • the per-item calls see no query (verified to fail against the old code)
  • $sort/$limit/$skip still shape the find, incl. ordering
  • $select reaches the per-item calls, while the find only selects the id

The previous does not forward selection filters to the single calls test asserted the old behaviour and is replaced.

pnpm test green: 1255 tests, no lint errors, no type errors, change-many.ts at 100% lines.

🤖 Generated with Claude Code

The query of `patchMany`/`removeMany` selects *which* items are affected and
is consumed by the `find` of the per-item fallback. Re-applying it to every
`patch(id, ...)`/`remove(id, ...)` call was redundant at best: adapters use
`params.query` as an additional filter, so a stale item throws `NotFound` and
takes the whole `Promise.all` down with it - after partially written changes.

- the per-item calls now only get `$select` from the query
- the fallback `find` replaces `$select` with the id property, since it is
  only there to collect the ids

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fratzinger
fratzinger merged commit 9c5343b into main Sep 8, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant