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
- 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
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
- Always re-fetch the table immediately before migrating - never reuse cached Table objects
- Check for concurrent schema edits before running batch migrations
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
- Column "${newColumn.name}" is not a user column
- Column "${oldColumn.name}" is not a user relationship
- Column "${oldColumn.name}" is a one-to-many column but "${ne
- Column "${oldColumn.name}" is a ${oldColumn.relationshipType
- Unknown migration type
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/3bff84a0d63c2c11.
Report an issue: GitHub.