Skip to content

[Bug]: Update on delegate child model fails with "missing FROM-clause entry" when entity mutation plugins are present #2367

@genu

Description

@genu

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

  1. 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
}
  1. Register any entity mutation plugin with an afterEntityMutation hook:
client.$use({
    id: 'my-plugin',
    onEntityMutation: {
        afterEntityMutation() {
            // even a noop triggers the bug
        },
    },
});
  1. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions