{"record":{"id":"c0304c0f486b80d9","repo":"Budibase/budibase","slug":"failed-to-generate-a-unique-name-for-the-row-actio","errorCode":null,"errorMessage":"Failed to generate a unique name for the row action","messagePattern":"Failed to generate a unique name for the row action","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/builder/src/stores/builder/rowActions.ts","lineNumber":63,"sourceCode":"      [tableId]: actions,\n    }))\n  }\n\n  createRowAction = async (tableId: string, viewId?: string, name?: string) => {\n    if (!tableId) {\n      return\n    }\n\n    // Get a unique name for this action\n    if (!name) {\n      const existingRowActions = get(this)[tableId] || []\n      name = getSequentialName(existingRowActions, \"New row action \", {\n        getName: x => x.name,\n      })!\n    }\n\n    if (!name) {\n      throw new Error(\"Failed to generate a unique name for the row action\")\n    }\n\n    // Create the action\n    const res = await API.rowActions.create(tableId, name)\n\n    // Enable action on this view if adding via a view\n    if (viewId) {\n      await Promise.all([\n        this.enableView(tableId, res.id, viewId),\n        automationStore.actions.fetch(),\n      ])\n    } else {\n      await Promise.all([\n        this.refreshRowActions(tableId),\n        automationStore.actions.fetch(),\n      ])\n    }\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/builder/src/stores/builder/rowActions.ts#L45-L81","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nawait rowActions.create(tableId, \"\")\n// after\nawait rowActions.create(tableId, \"My custom action\")","handlingStrategy":"validation","validationCode":"if (!name?.trim()) {\n  name = `New row action ${Date.now()}`\n}","typeGuard":"const hasName = (n: string | undefined | null): n is string =>\n  typeof n === \"string\" && n.trim().length > 0","tryCatchPattern":"try {\n  await rowActions.create(tableId, name)\n} catch (e) {\n  if (e.message.includes(\"unique name for the row action\")) {\n    await rowActions.create(tableId, `New row action ${Date.now()}`)\n  } else throw e\n}","preventionTips":["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"],"tags":["builder","naming","row-actions","validation"],"backgroundTag":"name-generation-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}