{"record":{"id":"95219c1d64d0efeb","repo":"Budibase/budibase","slug":"column-name-cannot-be-empty","errorCode":null,"errorMessage":"Column name cannot be empty","messagePattern":"Column name cannot be empty","errorType":"validation","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/tables/migration.ts","lineNumber":37,"sourceCode":"import sdk from \"../..\"\nimport { EventType, updateLinks } from \"../../../db/linkedRows\"\nimport { isExternalTableID } from \"../../../integrations/utils\"\n\nexport interface MigrationResult {\n  tablesUpdated: Table[]\n}\n\nexport async function migrate(\n  table: Table,\n  oldColumnName: string,\n  newColumnName: string\n): Promise<MigrationResult> {\n  if (newColumnName in table.schema) {\n    throw new BadRequestError(`Column \"${newColumnName}\" already exists`)\n  }\n\n  if (newColumnName === \"\") {\n    throw new BadRequestError(`Column name cannot be empty`)\n  }\n\n  if (isInternalColumnName(newColumnName)) {\n    throw new BadRequestError(`Column name cannot be a reserved column name`)\n  }\n\n  const oldColumn = table.schema[oldColumnName]\n\n  if (!oldColumn) {\n    throw new BadRequestError(\n      `Column \"${oldColumnName}\" does not exist on table \"${table.name}\"`\n    )\n  }\n\n  if (\n    oldColumn.type !== FieldType.LINK ||\n    oldColumn.tableId !== InternalTable.USER_METADATA\n  ) {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/tables/migration.ts#L19-L55","documentation":"migrate() validates that the new column name is non-empty before performing the relationship-column migration; an empty string would create an unusable schema key, so a BadRequestError is thrown.","triggerScenarios":"Calling migrate(table, oldColumnName, '') — typically an unset form input or unbound variable passed as the new name.","commonSituations":"UI submitting a rename form with a blank field; a variable that failed to initialize; trimming not applied to whitespace-only input (only strict '' is caught here).","solutions":["Pass a non-empty newColumnName after trimming user input","Validate the name in the caller before invoking migrate","Check that the variable holding the name is actually populated","Add a trim+length check in your request handler"],"exampleFix":"// before\nawait sdk.tables.migration.migrate(table, oldCol, userInput)\n// after\nconst name = userInput.trim()\nif (!name) throw new Error('New column name required')\nawait sdk.tables.migration.migrate(table, oldCol, name)","handlingStrategy":"validation","validationCode":"const name = (userInput ?? '').trim()\nif (!name) throw new Error('New column name is required')","typeGuard":"function isNonEmptyString(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0\n}","tryCatchPattern":"try {\n  await sdk.tables.migration.migrate(table, oldName, newName)\n} catch (e) {\n  if (e.message === 'Column name cannot be empty') {\n    // prompt for a valid name and retry\n  }\n}","preventionTips":["Trim and require non-empty names in forms before submitting","Guard unbound/optional variables passed as newName","Validate at the API handler boundary, not just in migrate"],"tags":["validation","migration","input"],"backgroundTag":"empty-column-name","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}