Budibase/budibase · error · Error

Cannot rename a linked column.

Error message

Cannot rename a linked column.

What it means

When save() is called with a renaming option and the target column is a relationship (FieldType.LINK), the rename is rejected because renaming linked columns would break the link documents between tables. Relationship columns must be managed through link operations instead.

Source

Thrown at packages/server/src/sdk/workspace/tables/internal/index.ts:120

  table = checkAutoColumns(table, oldTable)

  // saving a table is a complex operation, involving many different steps, this
  // has been broken out into a utility to make it more obvious/easier to manipulate
  const tableSaveFunctions = new TableSaveFunctions({
    userId: opts?.userId,
    oldTable,
    importRows: opts?.rowsToImport,
  })
  table = await tableSaveFunctions.before(table)

  let renaming = opts?.renaming
  if (renaming && renaming.old === renaming.updated) {
    renaming = undefined
  }

  // rename row fields when table column is renamed
  if (renaming && table.schema[renaming.updated]?.type === FieldType.LINK) {
    throw new Error("Cannot rename a linked column.")
  }

  let pendingColumnRenames = oldTable?.pendingColumnRenames
    ? oldTable.pendingColumnRenames
    : []
  if (renaming) {
    pendingColumnRenames = mergePendingColumnRenames(
      pendingColumnRenames,
      renaming
    )
  }
  if (pendingColumnRenames.length > 0) {
    table.pendingColumnRenames = pendingColumnRenames
  } else {
    delete table.pendingColumnRenames
  }

  table = await tableSaveFunctions.mid(table, renaming)

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Skip link-type columns in your rename loop and only rename non-relationship columns
  2. Convert the relationship to a bb-reference column first (see tables/migration.ts), then rename it
  3. Recreate the relationship column with the desired name and re-establish links
  4. Leave the link column name as-is; relationship names are display labels in most UIs

Example fix

// before
if (column.type === FieldType.LINK) {
  await sdk.tables.saveTable(table, { renaming: { old: name, updated: newName } })
}
// after
if (column.type !== FieldType.LINK) {
  await sdk.tables.saveTable(table, { renaming: { old: name, updated: newName } })
}
Defensive patterns

Strategy: validation

Validate before calling

function canRename(table: Table, renaming: { old: string, updated: string }): boolean {
  return table.schema[renaming.updated]?.type !== FieldType.LINK
}

Type guard

function isLinkColumn(col: FieldSchema | undefined): boolean {
  return col?.type === FieldType.LINK
}

Try / catch

try {
  await sdk.tables.saveTable(table, { renaming })
} catch (e) {
  if (e.message === 'Cannot rename a linked column.') {
    // skip the rename for this relationship column
  }
}

Prevention

When it happens

Trigger: Calling sdk.tables.saveTable with opts.renaming = { old, updated } where table.schema[updated].type === FieldType.LINK (a relationship column), including via the column-rename endpoint.

Common situations: Renaming a user relationship column via the builder/API during the user-column migration flow; scripted table refactors that blindly rename all columns.

Related errors


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