Budibase/budibase · error

Unable to assign roles - license required.

Error message

Unable to assign roles - license required.

What it means

The public API roles.assign function only works when the tenant has the 'expanded public API' feature flag enabled, which is license-gated. If the tenant's license does not include expanded public API access, the call is rejected up front with this message before any user records are read. It is a licensing entitlement check, not a permissions or authentication problem.

Source

Thrown at packages/pro/src/sdk/publicApi/roles.ts:19

import { db as dbCore } from "@budibase/backend-core"
import { isExpandedPublicApiEnabled } from "../features"
import { db as userDB } from "../users"

interface AssignmentOpts {
  role?: {
    appId: string
    roleId: string
  }
  appBuilder?: {
    appId: string
  }
  builder?: boolean
  admin?: boolean
}

export async function assign(userIds: string[], opts: AssignmentOpts) {
  if (!(await isExpandedPublicApiEnabled())) {
    throw new Error("Unable to assign roles - license required.")
  }
  const users = await userDB.bulkGet(userIds)
  for (let user of users) {
    if (opts.role && opts.role.roleId) {
      const prodWorkspaceId = dbCore.getProdWorkspaceID(opts.role.appId)
      user.roles[prodWorkspaceId] = opts.role.roleId
    }
    if (opts.appBuilder) {
      const prodWorkspaceId = dbCore.getProdWorkspaceID(opts.appBuilder.appId)
      const existing = user.builder?.apps || []
      user.builder = {
        apps: existing.concat([prodWorkspaceId]),
      }
    }
    if (opts.builder) {
      user.builder = {
        global: true,
      }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Upgrade the tenant's license to one that includes the expanded public API feature
  2. Verify license activation/refresh so isExpandedPublicApiEnabled() resolves true (check licensing cache and re-sync the license)
  3. Use the builder UI or internal API for role assignment instead of the public API if no license upgrade is possible
  4. Wrap the call and surface a clear 'license required' message to end users rather than a generic 500

Example fix

// before: assuming public API role assignment is always available
await publicApi.roles.assign(userIds, { role: { roleId: "ADMIN", appId } })
// after: check the feature flag first
const enabled = await isExpandedPublicApiEnabled()
if (!enabled) {
  throw new Error("Expanded public API requires a license upgrade")
}
await publicApi.roles.assign(userIds, { role: { roleId: "ADMIN", appId } })
Defensive patterns

Strategy: validation

Validate before calling

const enabled = await isExpandedPublicApiEnabled()
if (!enabled) throw new Error("Expanded public API requires a license upgrade")

Try / catch

try {
  await roles.assign(userIds, opts)
} catch (err: any) {
  if (err.message === "Unable to assign roles - license required.") {
    // surface upgrade prompt / use internal API
  } else { throw err }
}

Prevention

When it happens

Trigger: Calling POST roles assignment via the public API (roles.assign) on a tenant whose license lacks the expanded public API add-on; using public-API role endpoints on the free plan or an expired license.

Common situations: Self-hosted or free-tier tenant integrating role management via REST public API; an API integration built on another tenant's plan being pointed at a tenant without the entitlement; license not re-activated after renewal so the feature flag resolves false.

Related errors


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