Skip to content

fix(orm): disallow include on models with no relation fields#2489

Open
Copilot wants to merge 7 commits intodevfrom
copilot/fix-arbitrary-include-type-checking
Open

fix(orm): disallow include on models with no relation fields#2489
Copilot wants to merge 7 commits intodevfrom
copilot/fix-arbitrary-include-type-checking

Conversation

Copy link
Contributor

Copilot AI commented Mar 17, 2026

  • Add HasRelations type helper in crud-types.ts
  • Gate include in SelectIncludeOmit behind HasRelations
  • Add compile-time regression test in typecheck.ts
  • Fix build errors from TypeScript not finding include on generic FindArgs union type
  • Replace (payload as any).include with 'include' in payload checks in lateral-join-dialect-base.ts and sqlite.ts
  • Simplify HasRelations to RelationFields<Schema, Model> extends never ? false : true
  • Restore BeforeEntityMutationCallback cast in zenstack-query-executor.ts (TS2321 reappears in full CI build)
Original prompt

This section details on the original issue you should resolve

<issue_title>Arbitrary include is allowed by type checking even when the model has no relation field.</issue_title>
<issue_description>```zmodel
model Dummy {
id Int @id @default(autoincrement())
name String
}


Then the below query code could pass the typechecking, and runtime will throw error:
```ts
  const dummies = await db.dummy.findMany({
    include: {
      abcdefg: true,
    },
  });

For this case it's better to not allow to use include at all, which is consistent with v2 behavior</issue_description>

<agent_instructions>This is caused by the type SelectIncludeOmit in crud-types.ts file</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…deOmit)

Co-authored-by: jiashengguo <16688722+jiashengguo@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix arbitrary include allowance by type checking Fix: disallow include on models with no relation fields Mar 17, 2026
Copilot AI requested a review from jiashengguo March 17, 2026 05:25
@jiashengguo jiashengguo marked this pull request as ready for review March 17, 2026 05:48
@jiashengguo
Copy link
Member

@copilot there is build error, fix it

Co-authored-by: jiashengguo <16688722+jiashengguo@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 17, 2026

@copilot there is build error, fix it

Fixed in b9d581e. The build errors were in three places where the HasRelations conditional type change caused TypeScript to no longer guarantee include exists on generic FindArgs<Schema, GetModels<Schema>, ...> types:

  1. lateral-join-dialect-base.ts and sqlite.ts — cast to (payload as any).include for the runtime include access checks
  2. zenstack-query-executor.tsTS2321: Excessive stack depth resolved by casting beforeEntityMutation to BeforeEntityMutationCallback<SchemaDef> (following the existing // tsc perf pattern in the file)

}

if (typeof payload === 'object' && payload.include && typeof payload.include === 'object') {
if (typeof payload === 'object' && (payload as any).include && typeof (payload as any).include === 'object') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not cast it to any, add a 'include' in payload check should be good to go.

the same for other changes in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 46ea0e2. Replaced all (payload as any).include casts with 'include' in payload checks in both lateral-join-dialect-base.ts and sqlite.ts.

…owing checks

Co-authored-by: jiashengguo <16688722+jiashengguo@users.noreply.github.com>
@ymc9 ymc9 changed the title Fix: disallow include on models with no relation fields fix: disallow include on models with no relation fields Mar 17, 2026
@ymc9 ymc9 changed the title fix: disallow include on models with no relation fields fix(orm): disallow include on models with no relation fields Mar 17, 2026
Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 17, 2026

@copilot there is build error, fix it

The build errors from the HasRelations type change were fixed in b9d581e (using as any casts initially), then improved in 46ea0e2 to use proper 'include' in payload narrowing instead. The HasRelations type itself was also simplified in 1a5c437.

Copilot AI requested a review from ymc9 March 17, 2026 21:16
Copilot finished work on behalf of ymc9 March 17, 2026 21:16
…ns simplification

Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
Copilot AI requested a review from ymc9 March 17, 2026 21:18
Copilot finished work on behalf of ymc9 March 17, 2026 21:18
@ymc9
Copy link
Member

ymc9 commented Mar 18, 2026

@copilot build is failing again

…ck depth in CI build

Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 18, 2026

@copilot build is failing again

Fixed in 5292a9f. The TS2321: Excessive stack depth error at zenstack-query-executor.ts:358 only surfaces in the full CI build (not in a standalone tsc --noEmit on the package). Restored the BeforeEntityMutationCallback<SchemaDef> cast — the HasRelations conditional type still produces deep enough type expansion to trigger this in the monorepo build context.

Copilot finished work on behalf of ymc9 March 18, 2026 02:27
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.

Arbitrary include is allowed by type checking even when the model has no relation field.

3 participants