Skip to content

Bug: createManyAndReturn with PolicyPlugin fails when rows have asymmetric optional fields #2460

@pkudinov

Description

@pkudinov

Description and expected behavior

createManyAndReturn throws Invariant failed: expecting a ValueNode when the PolicyPlugin is active and rows in the batch have asymmetric optional
fields — one row provides an optional field, another omits it.

When Kysely normalizes asymmetric rows into a uniform VALUES clause, it pads missing columns with DefaultInsertValueNode. The policy handler's
unwrapCreateValueRow doesn't recognize this node type and crashes.

Expected: returns the created items successfully.

Minimal reproduction:

model User {
    id   Int    @id @default(autoincrement())
    role String
    @@allow('all', true)
}

model Item {
    id   Int     @id @default(autoincrement())
    key  String                                                                                                                                        
    note String?
    @@allow('all', auth().role == 'admin')                                                                                                             
}                                                         
const user = await db.user.create({ data: { role: 'admin' } });
                                                                                                                                                       
await db.$setAuth(user).item.createManyAndReturn({                                                                                                     
    data: [                                                                                                                                            
        { key: 'a', note: 'hello' },                                                                                                                   
        { key: 'b' },              // omits `note`        
    ],
});
// Error: Invariant failed: expecting a ValueNode

Environment (please complete the following information):

  • ZenStack version: 3.4.5
  • Database type: PostgreSQL
  • Node.js version: 22.14.0
  • Package manager: pnpm

Additional context

  • Works fine without PolicyPlugin (raw client)
  • Works fine when all rows provide the same set of fields
  • Not specific to any field type — reproducible with plain String?, Decimal?, etc.
  • Fix: handle DefaultInsertValueNode in PolicyHandler.unwrapCreateValueRow by treating it as null

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions