{"record":{"id":"179cf408ec40ad49","repo":"Budibase/budibase","slug":"column-oldcolumnname-does-not-exist-on-table","errorCode":null,"errorMessage":"Column \"${oldColumnName}\" does not exist on table \"${table.name}\"","messagePattern":"Column \"(.+?)\" does not exist on table \"(.+?)\"","errorType":"validation","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/tables/migration.ts","lineNumber":47,"sourceCode":"  oldColumnName: string,\n  newColumnName: string\n): Promise<MigrationResult> {\n  if (newColumnName in table.schema) {\n    throw new BadRequestError(`Column \"${newColumnName}\" already exists`)\n  }\n\n  if (newColumnName === \"\") {\n    throw new BadRequestError(`Column name cannot be empty`)\n  }\n\n  if (isInternalColumnName(newColumnName)) {\n    throw new BadRequestError(`Column name cannot be a reserved column name`)\n  }\n\n  const oldColumn = table.schema[oldColumnName]\n\n  if (!oldColumn) {\n    throw new BadRequestError(\n      `Column \"${oldColumnName}\" does not exist on table \"${table.name}\"`\n    )\n  }\n\n  if (\n    oldColumn.type !== FieldType.LINK ||\n    oldColumn.tableId !== InternalTable.USER_METADATA\n  ) {\n    throw new BadRequestError(\n      `Only user relationship migration columns is currently supported`\n    )\n  }\n\n  const type =\n    oldColumn.relationshipType === RelationshipType.ONE_TO_MANY\n      ? FieldType.BB_REFERENCE_SINGLE\n      : FieldType.BB_REFERENCE\n  const newColumn: FieldSchema = {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/tables/migration.ts#L29-L65","documentation":"migrate() looks up table.schema[oldColumnName]; if the source column doesn't exist, there is nothing to migrate, so a BadRequestError naming the column and table is thrown.","triggerScenarios":"Calling migrate(table, oldColumnName, newColumnName) where oldColumnName is not a key in the passed table's schema — due to a typo, a stale table object, or the column already having been migrated/renamed.","commonSituations":"Re-running a completed migration (old column already removed); referencing the column by display name instead of schema key; table fetched before a concurrent rename.","solutions":["Verify oldColumnName exists: `oldColumnName in table.schema` before calling","Re-fetch the latest table document — your copy may be stale","Check whether the migration already ran and the old column was removed","Confirm you're using the schema key, not a label/derived name"],"exampleFix":"// before\nawait sdk.tables.migration.migrate(table, 'usr', 'owner')\n// after\nif ('usr' in table.schema) {\n  await sdk.tables.migration.migrate(table, 'usr', 'owner')\n}","handlingStrategy":"validation","validationCode":"const freshTable = await sdk.tables.get(table._id!)\nif (!(oldColumnName in freshTable.schema)) {\n  throw new Error(`Column \"${oldColumnName}\" not found`)\n}","typeGuard":"function columnExists(table: Table, name: string): boolean {\n  return name in table.schema\n}","tryCatchPattern":"try {\n  await sdk.tables.migration.migrate(table, oldName, newName)\n} catch (e) {\n  if (e.message.includes('does not exist on table')) {\n    // re-fetch table or check whether migration already completed\n  }\n}","preventionTips":["Always operate on a freshly fetched table document","Verify the exact schema key (not display label) before migrating","Make migrations idempotent — skip if the old column is already gone"],"tags":["validation","migration","columns"],"backgroundTag":"column-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}