{"record":{"id":"a6e0ce81dcfd90ed","repo":"toeverything/AFFiNE","slug":"table-tablename-there-should-be-only-one-fi","errorCode":null,"errorMessage":"[Table(${tableName})]: There should be only one field marked as primary key. Found [${primaryFields.join(', ')}].","messagePattern":"\\[Table\\((.+?)\\)\\]: There should be only one field marked as primary key\\. Found \\[(.+?)\\]\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/common/infra/src/orm/core/validators/schema.ts","lineNumber":24,"sourceCode":"      if (!Object.values(table).some(field => field.schema.isPrimaryKey)) {\n        throw new Error(\n          `[Table(${tableName})]: There should be at least one field marked as primary key.`\n        );\n      }\n    },\n  },\n  OnlyOnePrimaryKey: {\n    validate(tableName, table) {\n      const primaryFields = [];\n\n      for (const name in table) {\n        if (table[name].schema.isPrimaryKey) {\n          primaryFields.push(name);\n        }\n      }\n\n      if (primaryFields.length > 1) {\n        throw new Error(\n          `[Table(${tableName})]: There should be only one field marked as primary key. Found [${primaryFields.join(', ')}].`\n        );\n      }\n    },\n  },\n  PrimaryKeyShouldNotBeOptional: {\n    validate(tableName, table) {\n      for (const name in table) {\n        const opts = table[name].schema;\n        if (opts.isPrimaryKey && opts.optional && !opts.default) {\n          throw new Error(\n            `[Table(${tableName})]: Field '${name}' can't be marked primary key and optional with no default value provider at the same time.`\n          );\n        }\n      }\n    },\n  },\n};","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/common/infra/src/orm/core/validators/schema.ts#L6-L42","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nexport const Member = t.table('member', {\n  workspaceId: t.string().primaryKey(),\n  userId: t.string().primaryKey(),\n});\n\n// after\nexport const Member = t.table('member', {\n  id: t.string().primaryKey(),\n  workspaceId: t.string(),\n  userId: t.string(),\n});","handlingStrategy":"validation","validationCode":"const pkCount = Object.values(fields).filter(f => f.isPrimaryKey).length;\nif (pkCount > 1) throw new Error('composite primary keys are not supported — use a synthetic id');","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["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"],"tags":["orm","schema","primary-key","affine"],"backgroundTag":"multiple-primary-keys","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}