{"record":{"id":"7c1caff1863ebed4","repo":"Budibase/budibase","slug":"column-table-primarydisplay-cannot-be-used-as","errorCode":null,"errorMessage":"Column \"${table.primaryDisplay}\" cannot be used as a display type.","messagePattern":"Column \"(.+?)\" cannot be used as a display type\\.","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/table/index.ts","lineNumber":126,"sourceCode":"    }, {})\n    return Object.keys(updates).length ? { ...row, ...updates } : row\n  })\n}\n\nasync function guardTable(table: Table, isCreate: boolean) {\n  checkDefaultFields(table)\n\n  if (\n    table.primaryDisplay &&\n    !canBeDisplayColumn(table.schema[table.primaryDisplay]?.type)\n  ) {\n    // Prevent throwing errors from existing badly configured tables. Only throw for new tables or if this setting is being updated\n    if (\n      isCreate ||\n      (await sdk.tables.getTable(table._id!)).primaryDisplay !==\n        table.primaryDisplay\n    ) {\n      throw new HTTPError(\n        `Column \"${table.primaryDisplay}\" cannot be used as a display type.`,\n        400\n      )\n    }\n  }\n}\n\n// covers both internal and external\nexport async function fetch(ctx: UserCtx<void, FetchTablesResponse>) {\n  const internal = await sdk.tables.getAllInternalTables()\n\n  const datasources = await sdk.datasources.getExternalDatasources()\n\n  const external: Table[] = []\n  for (const datasource of datasources) {\n    let entities = datasource.entities\n    if (entities) {\n      for (const entity of Object.values(entities)) {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/table/index.ts#L108-L144","documentation":"A table's primaryDisplay must reference a column that exists and is eligible as a display column. guardTable rejects saves where primaryDisplay points at an invalid column, but only when the table is newly created or the primaryDisplay value is actually changing — to avoid breaking legacy misconfigured tables.","triggerScenarios":"Creating a table with primaryDisplay set to a nonexistent/ineligible column, or updating an existing table's primaryDisplay to such a column (compared against the stored table's current primaryDisplay via sdk.tables.getTable).","commonSituations":"API scripts setting primaryDisplay to a field name that was renamed or deleted; picking an auto-column or unsupported type as display; importing table JSON from another app with different columns.","solutions":["Set primaryDisplay to an existing schema column name (exact key from table.schema)","Fetch the table first (GET /tables/:id) and copy a valid schema key into primaryDisplay","If the old table already has a bad primaryDisplay, fix it via a save that changes the value once — the guard only throws on create/change"],"exampleFix":"// before\nawait api.post('/tables', { name: \"Customers\", primaryDisplay: \"fullName\", schema: { name: {...} } })\n// after\nawait api.post('/tables', { name: \"Customers\", primaryDisplay: \"name\", schema: { name: {...} } })","handlingStrategy":"validation","validationCode":"function isDisplayCandidate(table, col) {\n  const field = table.schema?.[col]\n  return Boolean(field) && !\"link\".includes(field.type) && col !== table._id\n}\nconst current = await api.getTable(id).catch(() => null)\nif ((!current || current.primaryDisplay !== table.primaryDisplay) && !isDisplayCandidate(table, table.primaryDisplay)) {\n  throw new Error(\"primaryDisplay must be an existing schema column\")\n}","typeGuard":"const validDisplay = (t, col) => Object.prototype.hasOwnProperty.call(t?.schema || {}, col)","tryCatchPattern":"try {\n  await api.saveTable(table)\n} catch (e) {\n  if (e?.status === 400 && /cannot be used as a display type/.test(e.message)) {\n    const firstCol = Object.keys(table.schema)[0]\n    // retry with a known-valid column as primaryDisplay\n  } else throw e\n}","preventionTips":["Copy primaryDisplay values from schema keys, never from labels","Re-check primaryDisplay after renaming or deleting columns","Validate imports from other apps against actual schema keys","Prefer the Builder UI which lists eligible display columns"],"tags":["table","schema","primary-display"],"backgroundTag":"schema-validation-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}