Budibase/budibase · error · BadRequestError

Column "${oldColumn.name}" does not exist

Error message

Column "${oldColumn.name}" does not exist

What it means

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.

Source

Thrown at packages/server/src/sdk/workspace/tables/migration.ts:110

interface ColumnMigrator {
  doMigration(): Promise<MigrationResult>
}

function getColumnMigrator(
  table: Table,
  oldColumn: FieldSchema,
  newColumn: FieldSchema
): ColumnMigrator {
  // For now, we're only supporting migrations of user relationships to user
  // columns in internal tables. In the future, we may want to support other
  // migrations but for now return an error if we aren't migrating a user
  // relationship.
  if (isExternalTableID(table._id!)) {
    throw new BadRequestError("External tables cannot be migrated")
  }

  if (!(oldColumn.name in table.schema)) {
    throw new BadRequestError(`Column "${oldColumn.name}" does not exist`)
  }

  if (
    newColumn.type !== FieldType.BB_REFERENCE_SINGLE &&
    newColumn.type !== FieldType.BB_REFERENCE
  ) {
    throw new BadRequestError(`Column "${newColumn.name}" is not a user column`)
  }

  if (newColumn.subtype !== BBReferenceFieldSubType.USER) {
    throw new BadRequestError(`Column "${newColumn.name}" is not a user column`)
  }

  if (!isRelationshipField(oldColumn)) {
    throw new BadRequestError(
      `Column "${oldColumn.name}" is not a user relationship`
    )
  }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Re-fetch the table (sdk.tables.get) immediately before migrating and confirm the column exists
  2. Check `oldColumn.name in table.schema` before calling the migrator
  3. Rename the column back or choose the correct current column name

Example fix

// before
const table = await getTableSomehow()
await migrate(table, "users", "userRef")
// after
const fresh = await sdk.tables.get(table._id!)
if (!("users" in fresh.schema)) throw new Error("users column no longer exists")
await migrate(fresh, "users", "userRef")
Defensive patterns

Strategy: validation

Validate before calling

if (!(oldColumn.name in table.schema)) {
  throw new Error(`Column ${oldColumn.name} no longer exists on ${table._id}`)
}

Type guard

const columnExists = (t: Table, name: string): boolean =>
  name in (t.schema ?? {})

Try / catch

try {
  await sdk.tables.migrate(table, oldName, newName)
} catch (e) {
  if (String(e.message).includes('does not exist')) {
    table = await sdk.tables.get(table._id!) // refresh and re-check
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/3bff84a0d63c2c11. Report an issue: GitHub.