I am moderately confident, i am not doing something wrong.
Description and expected behavior
Prior on Zenstack V2:
prisma required relations to have names in n+ scenario but 1 relation could remain unnamed. This is allowed even though not recommended.
After upgrading to V3:
When two relations connect the same pair of models and only one of the two relation pairs carries a @relation("name"), the unnamed pair resolves to the wrong opposite field. In the generated schema, the unnamed field's relation.opposite points at the named relation's foreign key, so relation filters (some/none/every) and nested reads traverse the wrong column and silently return incorrect results (no error, types still compile). Prisma resolves this schema correctly; ZenStack v3 does not.
Example
datasource db {
provider = 'postgresql'
url = env('DATABASE_URL')
}
model Category {
id String @id @default(cuid())
products Product[] // unnamed — opposite SHOULD be Product.category
featured Product[] @relation("Featured")
}
model Product {
id String @id @default(cuid())
category Category @relation(fields: [categoryId], references: [id])
categoryId String
featuredIn Category? @relation("Featured", fields: [featuredInId], references: [id])
featuredInId String?
}
Expected: Category.products ↔ Product.category (categoryId); Category.featured ↔ Product.featuredIn (featuredInId).
Actual: generated schema gives Category.products.relation.opposite = "featuredIn" (should be "category") — both products and featured resolve to featuredIn.
Observable symptom:
await db.category.findMany({ where: { products: { none: {} } } });
compiles to the wrong join column:
where not exists (
select 1 from "Product"
where "Category"."id" = "Product"."featuredInId" -- ❌ should be "Product"."categoryId"
)
Workaround: name both relation pairs (@relation("CategoryProducts") on products/category, plus the existing "Featured").
I also found an that field ordering change how field was resolved.
Another reason why this is an issue is because I use relation fields in my BaseEntity and extend, those cant really be named...
Environment (please complete the following information):
- ZenStack version: 3.7.* cant test on 3.8.*
- Database type: Postgresql
- Node.js/Bun version: 24
- Package manager: yarn
Additional context
Sounded like this would fix
fix(cli): add missing opposite relation fields during db pull when multiple FKs target the same model (https://github.com/zenstackhq/zenstack/pull/2652[)](https://github.com/zenstackhq/zenstack/commit/e492c937ddb07411531dabd3ca9182ec2be53b3a)
Description and expected behavior
Prior on Zenstack V2:
prisma required relations to have names in n+ scenario but 1 relation could remain unnamed. This is allowed even though not recommended.
After upgrading to V3:
When two relations connect the same pair of models and only one of the two relation pairs carries a @relation("name"), the unnamed pair resolves to the wrong opposite field. In the generated schema, the unnamed field's relation.opposite points at the named relation's foreign key, so relation filters (some/none/every) and nested reads traverse the wrong column and silently return incorrect results (no error, types still compile). Prisma resolves this schema correctly; ZenStack v3 does not.
Example
Expected: Category.products ↔ Product.category (categoryId); Category.featured ↔ Product.featuredIn (featuredInId).
Actual: generated schema gives Category.products.relation.opposite = "featuredIn" (should be "category") — both products and featured resolve to featuredIn.
Observable symptom:
compiles to the wrong join column:
Workaround: name both relation pairs (@relation("CategoryProducts") on products/category, plus the existing "Featured").
I also found an that field ordering change how field was resolved.
Another reason why this is an issue is because I use relation fields in my BaseEntity and extend, those cant really be named...
Environment (please complete the following information):
Additional context
Sounded like this would fix
fix(cli): add missing opposite relation fields during db pull when multiple FKs target the same model (https://github.com/zenstackhq/zenstack/pull/2652[)](https://github.com/zenstackhq/zenstack/commit/e492c937ddb07411531dabd3ca9182ec2be53b3a)