Budibase/budibase · error · BadRequestError
Column "${newColumnName}" already exists
Error message
Column "${newColumnName}" already exists What it means
migrate() (user relationship column migration) first checks that the target column name is not already present in table.schema; if it is, the migration would overwrite an existing column, so a BadRequestError is thrown.
Source
Thrown at packages/server/src/sdk/workspace/tables/migration.ts:33
Row,
Table,
} from "@budibase/types"
import { cloneDeep } from "lodash"
import sdk from "../.."
import { EventType, updateLinks } from "../../../db/linkedRows"
import { isExternalTableID } from "../../../integrations/utils"
export interface MigrationResult {
tablesUpdated: Table[]
}
export async function migrate(
table: Table,
oldColumnName: string,
newColumnName: string
): Promise<MigrationResult> {
if (newColumnName in table.schema) {
throw new BadRequestError(`Column "${newColumnName}" already exists`)
}
if (newColumnName === "") {
throw new BadRequestError(`Column name cannot be empty`)
}
if (isInternalColumnName(newColumnName)) {
throw new BadRequestError(`Column name cannot be a reserved column name`)
}
const oldColumn = table.schema[oldColumnName]
if (!oldColumn) {
throw new BadRequestError(
`Column "${oldColumnName}" does not exist on table "${table.name}"`
)
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Choose a different newColumnName that doesn't exist in the schema
- Check `newColumnName in table.schema` before calling and handle gracefully
- If the migration partially ran, clean up or resume from the already-created column rather than re-running
- Verify the table document is current (re-fetch) — stale table objects may miss a recently added column
Example fix
// before
await sdk.tables.migration.migrate(table, 'user', 'owner')
// after
if (!('owner' in table.schema)) {
await sdk.tables.migration.migrate(table, 'user', 'owner')
} Defensive patterns
Strategy: validation
Validate before calling
if (newColumnName in table.schema) {
throw new Error(`Pick a different name; "${newColumnName}" exists`)
} Try / catch
try {
await sdk.tables.migration.migrate(table, oldName, newName)
} catch (e) {
if (e.message.includes('already exists')) {
// choose another name or resume the partial migration
}
} Prevention
- Check schema keys before calling migrate
- Re-fetch the table to avoid stale schema snapshots
- Handle retries idempotently — the first run may have added the column already
- Validate user-supplied names against existing fields in the UI
When it happens
Trigger: Calling sdk.tables.migration.migrate(table, oldColumnName, newColumnName) where newColumnName already exists as a key in the table's schema (case-sensitive check).
Common situations: Retrying a partially-completed migration that already added the new column; picking a name that collides with another field; UI letting users type an existing field name.
Related errors
- Column "${oldColumnName}" does not exist on table "${table.n
- Column name cannot be empty
- Column name cannot be a reserved column name
- External tables cannot be migrated
- Error getting status
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/c17a0a83c847c96c.
Report an issue: GitHub.