{"record":{"id":"a420f380da62c377","repo":"remix-run/remix","slug":"table-tablename-primarykey-must-contain-at-lea","errorCode":null,"errorMessage":"Table \"{tableName}\" primaryKey must contain at least one column","messagePattern":"Table \"(.+?)\" primaryKey must contain at least one column","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/data-table/src/lib/table.ts","lineNumber":1104,"sourceCode":"function normalizePrimaryKey(\n  tableName: string,\n  columns: TableColumnsDefinition,\n  primaryKey?: string | readonly string[],\n): string[] {\n  if (primaryKey === undefined) {\n    if (!Object.prototype.hasOwnProperty.call(columns, 'id')) {\n      throw new Error(\n        'Table \"' + tableName + '\" must include an \"id\" column or an explicit primaryKey',\n      )\n    }\n\n    return ['id']\n  }\n\n  let keys = Array.isArray(primaryKey) ? [...primaryKey] : [primaryKey]\n\n  if (keys.length === 0) {\n    throw new Error('Table \"' + tableName + '\" primaryKey must contain at least one column')\n  }\n\n  for (let key of keys) {\n    if (!Object.prototype.hasOwnProperty.call(columns, key)) {\n      throw new Error('Table \"' + tableName + '\" primaryKey column \"' + key + '\" does not exist')\n    }\n  }\n\n  return keys\n}\n\nfunction normalizeKeySelector<table extends AnyTable>(\n  table: table,\n  selector: KeySelector<table> | undefined,\n  optionName: string,\n  defaultValue: readonly string[],\n): string[] {\n  return normalizeKeysForTable(table, selector, optionName, defaultValue)","sourceCodeStart":1086,"sourceCodeEnd":1122,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table/src/lib/table.ts#L1086-L1122","documentation":"An explicitly provided primaryKey option must list at least one column. This error is thrown when primaryKey is an empty array (or equivalent), which would leave the table with no primary key at all.","triggerScenarios":"Passing primaryKey: [] programmatically, e.g. when a list of key columns is computed from config or user input and comes back empty.","commonSituations":"Dynamic schema generation where the key list is derived from data that is empty in some environment; spread defaults that accidentally override a real key list.","solutions":["Provide at least one column name in the primaryKey array","Guard dynamic key lists: fall back to ['id'] when the computed list is empty","Check for accidental spreads like { ...defaults, primaryKey: [] }"],"exampleFix":"// before\ncreateTable('t', cols, { primaryKey: computedKeys })\n// after\ncreateTable('t', cols, { primaryKey: computedKeys.length > 0 ? computedKeys : ['id'] })","handlingStrategy":"validation","validationCode":"if (keys.length === 0) throw new Error('primaryKey must not be empty')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Guard dynamically computed key lists with a non-empty fallback","Never spread option objects that may set primaryKey to []"],"tags":["data-table","primary-key","schema"],"backgroundTag":"missing-primary-key","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}