Budibase/budibase · error · BadRequestError
Column "${oldColumn.name}" is not a user relationship
Error message
Column "${oldColumn.name}" is not a user relationship What it means
The source column of a user migration must be a relationship (LINK) column. getColumnMigrator uses the isRelationshipField type guard and throws this BadRequestError when oldColumn is not a RelationshipFieldMetadata, i.e. it's a plain field (string, number, bb reference, etc.).
Source
Thrown at packages/server/src/sdk/workspace/tables/migration.ts:125
}
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`
)
}
if (oldColumn.tableId !== InternalTable.USER_METADATA) {
throw new BadRequestError(
`Column "${oldColumn.name}" is not a user relationship`
)
}
if (oldColumn.relationshipType === RelationshipType.ONE_TO_MANY) {
if (newColumn.type !== FieldType.BB_REFERENCE_SINGLE) {
throw new BadRequestError(
`Column "${oldColumn.name}" is a one-to-many column but "${newColumn.name}" is not a single user column`
)
}
return new SingleUserColumnMigrator(table, oldColumn, newColumn)
}View on GitHub (pinned to a81a902e9a)
Solutions
- Only pass columns where oldColumn.type === FieldType.LINK to the migrator
- Filter the table schema: pick entries where isRelationshipField(col) is true
- If the data lives in a non-link column, a custom data import is needed - the migrator only converts relationships
Example fix
// before await migrate(table, "ownerName", "owner") // after const col = table.schema["ownerName"] if (col?.type === FieldType.LINK) await migrate(table, "ownerName", "owner")
Defensive patterns
Strategy: type-guard
Validate before calling
if (!isRelationshipField(oldColumn)) {
throw new Error(`${oldColumn.name} is not a link column`)
} Type guard
const isMigratableSource = (c: FieldSchema): c is RelationshipFieldMetadata => isRelationshipField(c)
Prevention
- Filter candidate columns with isRelationshipField before migration
- Remember only FieldType.LINK columns are supported migration sources
When it happens
Trigger: Calling the migrator with an oldColumn whose type is not FieldType.LINK - e.g. trying to "migrate" a text or lookup column into a user column.
Common situations: Scripts iterating all columns of a table without filtering to type "link"; misunderstanding that only relationship-to-user-column migrations are supported.
Related errors
- Column "${oldColumn.name}" does not exist
- Column "${newColumn.name}" is not a user column
- 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/81d0c0f3437a7406.
Report an issue: GitHub.