toeverything/AFFiNE · error · Error
[Table(${tableName})]: There should be only one field marked
Error message
[Table(${tableName})]: There should be only one field marked as primary key. Found [${primaryFields.join(', ')}]. What it means
Schema validator OnlyOnePrimaryKey fires when more than one field in a table definition is marked .primaryKey(). The ORM supports only single-column primary keys; composite keys are rejected at definition time and the message lists every offending field name.
Source
Thrown at packages/common/infra/src/orm/core/validators/schema.ts:24
if (!Object.values(table).some(field => field.schema.isPrimaryKey)) {
throw new Error(
`[Table(${tableName})]: There should be at least one field marked as primary key.`
);
}
},
},
OnlyOnePrimaryKey: {
validate(tableName, table) {
const primaryFields = [];
for (const name in table) {
if (table[name].schema.isPrimaryKey) {
primaryFields.push(name);
}
}
if (primaryFields.length > 1) {
throw new Error(
`[Table(${tableName})]: There should be only one field marked as primary key. Found [${primaryFields.join(', ')}].`
);
}
},
},
PrimaryKeyShouldNotBeOptional: {
validate(tableName, table) {
for (const name in table) {
const opts = table[name].schema;
if (opts.isPrimaryKey && opts.optional && !opts.default) {
throw new Error(
`[Table(${tableName})]: Field '${name}' can't be marked primary key and optional with no default value provider at the same time.`
);
}
}
},
},
};View on GitHub (pinned to b4c8548c09)
Solutions
- Keep exactly one .primaryKey() (usually a synthetic id) and remove the marker from the other fields.
- For join/linking tables, give them a generated id primary key and store the two foreign keys as regular indexed fields.
- If you need uniqueness across columns, enforce it at the application layer (lookup before insert) since the ORM won't do composite uniqueness.
Example fix
// before
export const Member = t.table('member', {
workspaceId: t.string().primaryKey(),
userId: t.string().primaryKey(),
});
// after
export const Member = t.table('member', {
id: t.string().primaryKey(),
workspaceId: t.string(),
userId: t.string(),
}); Defensive patterns
Strategy: validation
Validate before calling
const pkCount = Object.values(fields).filter(f => f.isPrimaryKey).length;
if (pkCount > 1) throw new Error('composite primary keys are not supported — use a synthetic id'); Try / catch
try { registerTable(MyTable); } catch (e) { if (e instanceof Error && e.message.includes('only one field marked as primary key')) { /* demote extra PK fields to plain indexed fields */ } throw e; } Prevention
- Remember this ORM is single-column-PK only; give join tables a generated id
- Keep exactly one .primaryKey() per table by convention (always the id field)
- Cover multi-column uniqueness in app logic, not via extra PKs
When it happens
Trigger: Marking two columns (e.g. workspaceId and docId) with .primaryKey() to emulate a composite key; pasting a join-table definition from SQL habits where PRIMARY KEY (a, b) is normal.
Common situations: Porting a relational schema with composite keys; trying to enforce uniqueness on a secondary column by making it a primary key instead of adding a uniqueness check.
Related errors
- [Table(${tableName})]: There should be at least one field ma
- [Table(${tableName})]: Field '${name}' can't be marked prima
- ValueNotExists
- EdgelessExportError
- ValueNotExists
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/a6e0ce81dcfd90ed.
Report an issue: GitHub.