Description
Updating a child model in a delegate hierarchy fails with a SQL error when an entity mutation plugin with an afterEntityMutation hook is registered. The error is:
- PostgreSQL:
missing FROM-clause entry for table "Base"
- SQLite:
no such column: Base.field
Additional context
When any plugin registers an afterEntityMutation hook, the query executor globally replaces RETURNING "id" with RETURNING * on all UPDATE/INSERT queries (zenstack-query-executor.ts:224-234). This causes the following chain of events during a child model update:
Steps to Reproduce
- Define a delegate hierarchy where the base model has non-ID fields:
model Asset {
id Int @id @default(autoincrement())
organizationId String
assetType String
@@delegate(assetType)
}
model Product extends Asset {
name String
}
- Register any entity mutation plugin with an afterEntityMutation hook:
client.$use({
id: 'my-plugin',
onEntityMutation: {
afterEntityMutation() {
// even a noop triggers the bug
},
},
});
- Create and then update a child entity with data that touches both base and child fields:
const group = await client.Post.create({
data: { organizationId: 'org1', name: 'My Group' },
});
// This fails:
await client.Post.update({
where: { id: group.id },
data: { organizationId: 'org2', name: 'Updated Group' },
});
Notes
- The bug only triggers when the update includes child-specific fields (otherwise the child UPDATE is skipped entirely)
- The afterEntityMutation hook doesn't need to do anything — its mere presence causes RETURNING * globally via hasEntityMutationPluginsWithAfterMutationHooks
- Policy plugins are not required to reproduce the issue, though in practice users typically have both policy and entity mutation plugins active
Description
Updating a child model in a delegate hierarchy fails with a SQL error when an entity mutation plugin with an
afterEntityMutationhook is registered. The error is:missing FROM-clause entry for table "Base"no such column: Base.fieldAdditional context
When any plugin registers an
afterEntityMutationhook, the query executor globally replacesRETURNING "id"withRETURNING *on all UPDATE/INSERT queries (zenstack-query-executor.ts:224-234). This causes the following chain of events during a child model update:Steps to Reproduce
Notes