Closed
Description
Description and expected behavior
I'm using Zenstack with the TRPC generator & react-query plugin in a NextJS app.
Given the following zmodel:
plugin trpc {
provider = '@zenstackhq/trpc'
output = 'src/server/api/routers/generated'
version = 'v11'
importCreateRouter = "@/server/api/trpc"
importProcedure = "@/server/api/trpc"
zodSchemasImport = "@/lib/zenstack/zod"
generateClientHelpers = 'react'
}
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum UserType {
UserLocal
UserGoogle
}
model User {
id String @id @default(cuid())
type UserType
@@delegate(type)
userFolders UserFolder[]
}
model UserLocal extends User {
email String
password String
}
model UserGoogle extends User {
googleId String
}
model UserFolder {
id String @id @default(cuid())
userId String
path String
user User @relation(fields: [userId], references: [id])
}
When calling the autogenerated UserFolder.create
TRPC mutation as such:
const createUserFolderMutation = api.userFolder.create.useMutation();
....
await createUserFolderMutation.mutateAsync({
data: {
path: "/",
userId: localUser.id,
},
});
The request then fails with a Zod validation error:
❌ tRPC failed on userFolder.create: [
{
"code": "invalid_union",
"unionErrors": [
{
"issues": [
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [
"data",
"user"
],
"message": "Required"
},
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [
"data",
"delegate_aux_UserFolder_user_UserLocal"
],
"message": "Required"
},
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [
"data",
"delegate_aux_UserFolder_user_UserGoogl_0"
],
"message": "Required"
},
{
"code": "unrecognized_keys",
"keys": [
"userId"
],
"path": [
"data"
],
"message": "Unrecognized key(s) in object: 'userId'"
}
],
"name": "ZodError"
},
{
"issues": [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"data",
"delegate_aux_UserFolder_userId_UserLoc_0"
],
"message": "Required"
},
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"data",
"delegate_aux_UserFolder_userId_UserGoo_0"
],
"message": "Required"
}
],
"name": "ZodError"
}
],
"path": [
"data"
],
"message": "Invalid input"
}
]
Environment (please complete the following information):
- ZenStack version: 2.11.6
- Prisma version: 6.3.1
- Database type: Postgresql
Additional context
I can work around this issue by creating my own TRPC mutation, which uses the simpler UserFolderCreateSchema
as the input schema.
export default function createFixedRouter() {
return createTRPCRouter({
userFolderFixed: createTRPCRouter({
create: procedure
.input(z.object({ data: UserFolderCreateSchema }))
.mutation(({ ctx, input }) => getDb(ctx).userFolder.create(input)),
}),
});
}
I have created an example repo with the issue here:
https://github.com/diesal11/zenstack-trpc-zod-bug