{"record":{"id":"29b2ac6f7e70f739","repo":"remix-run/remix","slug":"missing-key-key-for-primary-key-lookup-on-ge","errorCode":null,"errorMessage":"Missing key \"{key}\" for primary key lookup on \"{getTableName(table)}\"","messagePattern":"Missing key \"(.+?)\" for primary key lookup on \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/data-table/src/lib/table.ts","lineNumber":1034,"sourceCode":"  value: PrimaryKeyInput<table>,\n): Partial<TableRow<table>> {\n  let keys = getTablePrimaryKey(table)\n\n  if (keys.length === 1 && (typeof value !== 'object' || value === null || Array.isArray(value))) {\n    let key = keys[0] as keyof TableRow<table>\n    return { [key]: value } as Partial<TableRow<table>>\n  }\n\n  if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n    throw new Error('Composite primary keys require an object value')\n  }\n\n  let objectValue = value as Record<string, unknown>\n  let output: Partial<TableRow<table>> = {}\n\n  for (let key of keys) {\n    if (!(key in objectValue)) {\n      throw new Error(\n        'Missing key \"' + key + '\" for primary key lookup on \"' + getTableName(table) + '\"',\n      )\n    }\n\n    ;(output as Record<string, unknown>)[key] = objectValue[key]\n  }\n\n  return output\n}\n\n/**\n * Builds a stable key for a row tuple.\n * @param row Source row.\n * @param columns Columns included in the tuple.\n * @returns Stable tuple key.\n */\nexport function getCompositeKey(row: Record<string, unknown>, columns: readonly string[]): string {\n  let values = columns.map((column) => stableSerialize(row[column]))","sourceCodeStart":1016,"sourceCodeEnd":1052,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table/src/lib/table.ts#L1016-L1052","documentation":"For composite primary keys, the lookup object must contain every column listed in the table's primaryKey. This error names the exact missing key so you can add it to the object you passed to the lookup API.","triggerScenarios":"Calling find/update with { tenantId: 'x' } when primaryKey is ['tenantId','postId']; also typos or camelCase/snake_case mismatches in the key name.","commonSituations":"Partial objects built from URL params that only carry some key segments, or renaming key columns without updating lookup call sites.","solutions":["Add the missing key named in the error message to your lookup object","Verify spelling/casing matches the column name in the table definition","Validate incoming params contain all primaryKey columns before the lookup"],"exampleFix":"// before\nlet row = await db.members.find({ tenantId })\n// after\nlet row = await db.members.find({ tenantId, memberId })","handlingStrategy":"validation","validationCode":"for (const key of primaryKeyColumns) {\n  if (!(key in value)) throw new Error(`missing key ${key}`)\n}","typeGuard":"const hasAllKeys = (v: object, keys: string[]) => keys.every((k) => k in v)","tryCatchPattern":null,"preventionTips":["Derive lookup objects from the table's declared primaryKey list","Validate request params contain all key segments before lookup"],"tags":["data-table","primary-key","lookup"],"backgroundTag":"composite-primary-key-lookup","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}