{"record":{"id":"3bff84a0d63c2c11","repo":"Budibase/budibase","slug":"column-oldcolumn-name-does-not-exist","errorCode":null,"errorMessage":"Column \"${oldColumn.name}\" does not exist","messagePattern":"Column \"(.+?)\" does not exist","errorType":"validation","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/tables/migration.ts","lineNumber":110,"sourceCode":"interface ColumnMigrator {\n  doMigration(): Promise<MigrationResult>\n}\n\nfunction getColumnMigrator(\n  table: Table,\n  oldColumn: FieldSchema,\n  newColumn: FieldSchema\n): ColumnMigrator {\n  // For now, we're only supporting migrations of user relationships to user\n  // columns in internal tables. In the future, we may want to support other\n  // migrations but for now return an error if we aren't migrating a user\n  // relationship.\n  if (isExternalTableID(table._id!)) {\n    throw new BadRequestError(\"External tables cannot be migrated\")\n  }\n\n  if (!(oldColumn.name in table.schema)) {\n    throw new BadRequestError(`Column \"${oldColumn.name}\" does not exist`)\n  }\n\n  if (\n    newColumn.type !== FieldType.BB_REFERENCE_SINGLE &&\n    newColumn.type !== FieldType.BB_REFERENCE\n  ) {\n    throw new BadRequestError(`Column \"${newColumn.name}\" is not a user column`)\n  }\n\n  if (newColumn.subtype !== BBReferenceFieldSubType.USER) {\n    throw new BadRequestError(`Column \"${newColumn.name}\" is not a user column`)\n  }\n\n  if (!isRelationshipField(oldColumn)) {\n    throw new BadRequestError(\n      `Column \"${oldColumn.name}\" is not a user relationship`\n    )\n  }","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/tables/migration.ts#L92-L128","documentation":"getColumnMigrator validates that the old column being migrated still exists in the table schema. If oldColumn.name is not a key of table.schema it throws this BadRequestError. This is a guard against migrating a stale/removed schema definition.","triggerScenarios":"Calling migrate/getColumnMigrator with a table object whose schema no longer contains the old column name - e.g. the column was deleted after the caller captured the table, or a hand-built table object omitted the column.","commonSituations":"Concurrent edits: another admin deleted or renamed the relationship column while a migration request was in flight; passing a cached/outdated Table object to the migration SDK.","solutions":["Re-fetch the table (sdk.tables.get) immediately before migrating and confirm the column exists","Check `oldColumn.name in table.schema` before calling the migrator","Rename the column back or choose the correct current column name"],"exampleFix":"// before\nconst table = await getTableSomehow()\nawait migrate(table, \"users\", \"userRef\")\n// after\nconst fresh = await sdk.tables.get(table._id!)\nif (!(\"users\" in fresh.schema)) throw new Error(\"users column no longer exists\")\nawait migrate(fresh, \"users\", \"userRef\")","handlingStrategy":"validation","validationCode":"if (!(oldColumn.name in table.schema)) {\n  throw new Error(`Column ${oldColumn.name} no longer exists on ${table._id}`)\n}","typeGuard":"const columnExists = (t: Table, name: string): boolean =>\n  name in (t.schema ?? {})","tryCatchPattern":"try {\n  await sdk.tables.migrate(table, oldName, newName)\n} catch (e) {\n  if (String(e.message).includes('does not exist')) {\n    table = await sdk.tables.get(table._id!) // refresh and re-check\n  }\n}","preventionTips":["Always re-fetch the table immediately before migrating - never reuse cached Table objects","Check for concurrent schema edits before running batch migrations"],"tags":["bad-request","schema","migration","missing-column"],"backgroundTag":"column-not-in-schema","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}