prisma/prisma · error
PSL_INVALID_RELATION_ATTRIBUTE
PSL_INVALID_RELATION_ATTRIBUTE
Error message
Backrelation list field "${model.name}.${field.name}" cannot declare fields/references; define them on the FK-side relation field What it means
Emitted while scanning backrelation (list-side) fields in `buildModelNodeFromPsl`. The non-owning side of a Prisma relation — the list field — must not declare `fields`/`references`; those belong exclusively on the FK-side (owning) relation field so the foreign key is built in exactly one place. When `interpretRelationAttribute` returns `fields` or `references` on a list/backrelation field, this diagnostic is pushed with the relation attribute's span and the field is skipped.
Source
Thrown at packages/2-sql/2-authoring/contract-psl/src/interpreter.ts:781
familyId: input.familyId,
targetId: input.targetId,
});
let relationName: string | undefined;
if (relationAttribute) {
const parsedRelation = interpretRelationAttribute({
selfModel: model,
field,
symbols: input.symbolTable,
sourceFile: input.sourceFile,
sourceId,
diagnostics,
});
if (!parsedRelation) {
continue;
}
if (parsedRelation.fields || parsedRelation.references) {
diagnostics.push({
code: 'PSL_INVALID_RELATION_ATTRIBUTE',
message: `Backrelation list field "${model.name}.${field.name}" cannot declare fields/references; define them on the FK-side relation field`,
sourceId,
span: relationAttribute.span,
});
continue;
}
if (
parsedRelation.onDelete ||
parsedRelation.onUpdate ||
parsedRelation.index !== undefined
) {
diagnostics.push({
code: 'PSL_INVALID_RELATION_ATTRIBUTE',
message: `Backrelation list field "${model.name}.${field.name}" cannot declare onDelete/onUpdate/index; define them on the FK-side relation field`,
sourceId,
span: relationAttribute.span,
});
continue;View on GitHub (pinned to 1243cdffbe)
Solutions
- Remove `fields:`/`references:` from the list field's `@relation`.
- Ensure the FK-side (the scalar/owning) field on the related model declares `@relation(fields: [...], references: [...])`.
Example fix
// before
model Post {
id Int @id
comments Comment[] @relation(fields: [id], references: [postId])
}
model Comment {
postId Int
post Post @relation(fields: [postId], references: [id])
}
// after
model Post {
id Int @id
comments Comment[]
}
model Comment {
postId Int
post Post @relation(fields: [postId], references: [id])
} Defensive patterns
Strategy: validation
Validate before calling
function findBackrelationWithFieldsOrReferences(psl) {
const issues = [];
for (const blk of psl.matchAll(/^model\s+(\w+)\s*\{([^}]*)\}/gms)) {
const modelName = blk[1];
for (const f of blk[2].matchAll(/(\w+)\s+[A-Za-z_]\w*\[\]\s+@relation\(([^)]*)\)/g)) {
if (/fields\s*:/.test(f[2]) || /references\s*:/.test(f[2]))
issues.push({ model: modelName, field: f[1] });
}
}
return issues;
} Type guard
import type { ContractSourceDiagnostic } from "@prisma-next/config/config-types";
export function isBackrelationFieldsReferencesDiagnostic(d: ContractSourceDiagnostic): d is ContractSourceDiagnostic & { code: 'PSL_INVALID_RELATION_ATTRIBUTE' } {
return d.code === 'PSL_INVALID_RELATION_ATTRIBUTE' && d.message.includes('cannot declare fields/references');
} Prevention
- On the list (back-relation) side, never set fields/references; those live on the FK-owning field.
- Remember a list-typed relation field is the many side and cannot own the foreign-key mapping.
- Put fields/references only on the single-valued relation field that owns the column.
When it happens
Trigger: Writing `model Post { comments Comment[] @relation(fields: [id]) }` on the list side. The loop detects the backrelation candidate, parses the `@relation` attribute, and finds `parsedRelation.fields || parsedRelation.references` present, which is invalid for the non-owning side.
Common situations: Copy-pasting the owning side's `@relation(fields: [...], references: [...])` onto the opposite list field; misunderstanding which side owns the foreign key; auto-formatting/importing from a Prisma schema that annotated both sides.
Related errors
- PSL_INVALID_ATTRIBUTE_SYNTAX
- PSL_JUNCTION_TARGET_FK_NOT_ID
- PSL_ORPHANED_BACKRELATION
- PSL_UNSUPPORTED_NAMESPACE_BLOCK
- PSL_INVALID_ATTRIBUTE_ARGUMENT
AI-assisted analysis of prisma/prisma@1243cdffbe (2026-08-01).
Data as JSON: /data/errors/b8c3467e93ab937f.json.
Report an issue: GitHub.