fix(client): preserve Prisma.skip through query extension args cloning#29198
Conversation
When using `Prisma.skip` with query extensions that define
`$allModels.$allOperations`, the `deepCloneArgs` utility would clone
Skip instances into plain `{}` objects, breaking the `instanceof`
check and causing validation errors like "Expected String, provided
Object".
The fix adds an `isSkip` check to `deepCloneValue` so Skip instances
pass through cloning unchanged, consistent with how ObjectEnumValue
and FieldRef are already handled.
Fixes prisma#25845
|
No actionable comments were generated in the recent review. 🎉 WalkthroughdeepCloneArgs was modified to treat Skip instances as non-cloneable so Changes
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…p tests Addresses CodeRabbit review nitpick: the prisma.$extends() query extension setup was duplicated across all five tests. Move it to a shared const at the describe block level to reduce repetition. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@CLAassistant check |
Merging this PR will degrade performance by 99.26%
Performance Changes
Comparing |
#29198) ## Problem When using `Prisma.skip` with query extensions (`$allModels.$allOperations`), the skip value gets silently converted to `{}` during argument cloning, causing runtime validation errors: ``` Argument `name`: Invalid value provided. Expected String or Null, provided Object. ``` This happens because `deepCloneArgs` treats the `Skip` instance as a regular object and clones it into a plain `{}`, which then fails the `instanceof Skip` check downstream in `serializeJsonQuery`. ## Fix Added `isSkip(x)` to the early-return condition in `deepCloneValue`, so `Skip` instances pass through cloning untouched — the same pattern already used for `ObjectEnumValue` and `FieldRef`. ## Tests - Added unit tests for `deepCloneArgs` verifying Skip preservation through cloning (top-level, nested, in arrays) - Added functional tests for `Prisma.skip` used with `$allModels.$allOperations` query extensions covering create, findMany (input fields and top-level args), include, and select Fixes #25845 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Preserve "skip" markers when cloning or processing arguments so skip behavior remains consistent and immutable across operations, including when query extensions are used. * **Tests** * Added tests validating skip preservation for top-level values, nested objects, arrays, and behavior across query extensions; also confirm regular values are deep-cloned (originals remain unchanged). <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Jacek Malec <malec@prisma.io>
Problem
When using
Prisma.skipwith query extensions ($allModels.$allOperations), the skip value gets silently converted to{}during argument cloning, causing runtime validation errors:This happens because
deepCloneArgstreats theSkipinstance as a regular object and clones it into a plain{}, which then fails theinstanceof Skipcheck downstream inserializeJsonQuery.Fix
Added
isSkip(x)to the early-return condition indeepCloneValue, soSkipinstances pass through cloning untouched — the same pattern already used forObjectEnumValueandFieldRef.Tests
deepCloneArgsverifying Skip preservation through cloning (top-level, nested, in arrays)Prisma.skipused with$allModels.$allOperationsquery extensions covering create, findMany (input fields and top-level args), include, and selectFixes #25845
Summary by CodeRabbit
Bug Fixes
Tests