Budibase/budibase · error
Failed to generate a unique name for the row action
Error message
Failed to generate a unique name for the row action
What it means
When creating a row action, the store tries a provided name or generates a sequential name (e.g. 'New row action 2'). If after both attempts no name is available, it throws rather than calling the API with an empty name. This is a defensive guard against getSequentialName failing (e.g. returning null/undefined via the non-null assertion).
Source
Thrown at packages/builder/src/stores/builder/rowActions.ts:63
[tableId]: actions,
}))
}
createRowAction = async (tableId: string, viewId?: string, name?: string) => {
if (!tableId) {
return
}
// Get a unique name for this action
if (!name) {
const existingRowActions = get(this)[tableId] || []
name = getSequentialName(existingRowActions, "New row action ", {
getName: x => x.name,
})!
}
if (!name) {
throw new Error("Failed to generate a unique name for the row action")
}
// Create the action
const res = await API.rowActions.create(tableId, name)
// Enable action on this view if adding via a view
if (viewId) {
await Promise.all([
this.enableView(tableId, res.id, viewId),
automationStore.actions.fetch(),
])
} else {
await Promise.all([
this.refreshRowActions(tableId),
automationStore.actions.fetch(),
])
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Pass an explicit unique name when creating the row action
- Ensure existing row actions all have valid name fields so getSequentialName can increment correctly
- Check for an empty-string name — falsy strings hit this throw too
- Retry creation; transient state inconsistency may have caused the generator to fail
Example fix
// before await rowActions.create(tableId, "") // after await rowActions.create(tableId, "My custom action")
Defensive patterns
Strategy: validation
Validate before calling
if (!name?.trim()) {
name = `New row action ${Date.now()}`
} Type guard
const hasName = (n: string | undefined | null): n is string => typeof n === "string" && n.trim().length > 0
Try / catch
try {
await rowActions.create(tableId, name)
} catch (e) {
if (e.message.includes("unique name for the row action")) {
await rowActions.create(tableId, `New row action ${Date.now()}`)
} else throw e
} Prevention
- Always pass an explicit, unique name when creating row actions
- Ensure existing row action records have valid name fields
- Avoid empty-string names (falsy values trigger this throw)
- Retry creation on transient naming collisions
When it happens
Trigger: Calling RowActionStore.create without a name while getSequentialName fails to produce a unique sequential name (its result coerced to null), e.g. if existingRowActions is malformed or the name-extractor getName returns undefined for entries.
Common situations: Creating row actions in bulk with race conditions; corrupted table metadata where existing actions lack name fields; passing an empty string name which is falsy and triggers the throw.
Related errors
- Source table '${relationship.sourceTable}' not found in data
- Target table '${relationship.targetTable}' not found in data
- Invalid custom REST template
- automationId and appId are required
- Query ID or Revision is missing
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/c0304c0f486b80d9.
Report an issue: GitHub.