{"record":{"id":"3bce50e698329ada","repo":"remix-run/remix","slug":"unknown-column-key-for-table-tablen","errorCode":null,"errorMessage":"Unknown column \"' + key + '\" for table \"' + tableName + '\"","messagePattern":"Unknown column \"' \\+ key \\+ '\" for table \"' \\+ tableName \\+ '\"","errorType":"validation","errorClass":"DataTableValidationError","httpStatus":null,"severity":"error","filePath":"packages/data-table/src/lib/database/write-lifecycle.ts","lineNumber":382,"sourceCode":"      {\n        metadata: {\n          table: tableName,\n          operation,\n          ...(source ? { source } : {}),\n        },\n      },\n    )\n  }\n\n  let output: Record<string, unknown> = {}\n\n  for (let key in value) {\n    if (!Object.prototype.hasOwnProperty.call(value, key)) {\n      continue\n    }\n\n    if (!Object.prototype.hasOwnProperty.call(columns, key)) {\n      throw new DataTableValidationError(\n        'Unknown column \"' + key + '\" for table \"' + tableName + '\"',\n        [],\n        {\n          metadata: {\n            table: tableName,\n            column: key,\n            operation,\n            ...(source ? { source } : {}),\n          },\n        },\n      )\n    }\n\n    output[key] = (value as Record<string, unknown>)[key]\n  }\n\n  return output\n}","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table/src/lib/database/write-lifecycle.ts#L364-L400","documentation":"After confirming the written value is an object, the library checks each key against the table's declared columns via getTableColumns. A key that is not a column of that table produces a DataTableValidationError naming the unknown column — this catches typos and renamed columns before they reach SQL, and also prevents accidental injection of stray properties.","triggerScenarios":"create({ values: { emial: 'a@b.com' } }) with the column spelled email; sending request JSON that includes extra fields (timestamps, ids, nested objects) not declared on the table; referencing a column after renaming it in the schema.","commonSituations":"Unvalidated request bodies forwarded straight into write APIs; schema drift between an API client and the table definition; spreading objects that carry extra metadata (e.g. joined rows) into an update.","solutions":["Fix the property name to match a declared column exactly","Whitelist/pick only known columns before writing: pick(values, ...columnNames)","If the field should exist, add the column to defineTable first"],"exampleFix":"// before\nawait userTable.create({ values: req.json() }) // contains extra fields\n\n// after\nlet body = req.json()\nawait userTable.create({\n  values: { name: body.name, email: body.email },\n})","handlingStrategy":"validation","validationCode":"let allowed = new Set(Object.keys(getTableColumns(table)))\nlet safe = Object.fromEntries(Object.entries(values).filter(([k]) => allowed.has(k)))\nawait table.create({ values: safe })","typeGuard":"function hasOnlyKnownColumns(values: Record<string, unknown>, columns: Record<string, unknown>): boolean {\n  return Object.keys(values).every((key) => Object.prototype.hasOwnProperty.call(columns, key))\n}","tryCatchPattern":"try {\n  await table.create({ values })\n} catch (error) {\n  if (error instanceof DataTableValidationError && /Unknown column/.test(error.message)) {\n    return new Response(error.message, { status: 400 })\n  } else throw error\n}","preventionTips":["Whitelist columns derived from the table schema before writing untrusted data","Keep API payload types in sync with table definitions","Run migrations and update code together when renaming columns"],"tags":["data-table","unknown-column","validation","schema-mismatch"],"backgroundTag":"unknown-column-in-payload","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}