{"record":{"id":"3b6e3f092959d568","repo":"Budibase/budibase","slug":"license-does-not-allow-translations","errorCode":null,"errorMessage":"License does not allow translations","messagePattern":"License does not allow translations","errorType":"http","errorClass":"ForbiddenError","httpStatus":403,"severity":"error","filePath":"packages/worker/src/api/controllers/global/configs.ts","lineNumber":346,"sourceCode":"    )\n    locales[locale] = {\n      ...localeConfig,\n      overrides,\n    }\n  }\n  return {\n    defaultLocale: config.defaultLocale,\n    locales,\n  }\n}\n\nasync function processTranslationsConfig(\n  ctx: UserCtx,\n  config: TranslationsConfigInner\n) {\n  const enabled = await pro.features.isTranslationsEnabled()\n  if (!enabled) {\n    throw new ForbiddenError(\"License does not allow translations\")\n  }\n  ctx.request.body.config = prepareTranslationsConfig(ctx, config)\n}\n\nasync function processSCIMConfig(\n  newConfig: SCIMInnerConfig,\n  existingConfig: SCIMInnerConfig | undefined\n): Promise<SCIMDisableAction | undefined> {\n  const { disableAction } = newConfig\n  delete newConfig.disableAction\n\n  const isBeingDisabled = existingConfig?.enabled && !newConfig.enabled\n  if (isBeingDisabled && disableAction) {\n    return disableAction\n  }\n}\n\nexport async function save(","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/worker/src/api/controllers/global/configs.ts#L328-L364","documentation":"processTranslationsConfig checks the translations entitlement before saving. If the license does not enable translations, a ForbiddenError is thrown and the config save is aborted before prepareTranslationsConfig runs.","triggerScenarios":"Saving a translations config (type translations) on a tenant whose license lacks the translations feature.","commonSituations":"Self-hosted/free tenants attempting to configure custom translations; expired license downgrading entitlements so previously-working saves now fail; license key missing from environment.","solutions":["Upgrade to a plan that includes translations","Re-apply or refresh the license key so the translations feature is entitled","Drop the translations section from the config save payload","After license changes, retry the save with the original payload"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const translationsAllowed = await pro.features.isTranslationsEnabled()\nif (!translationsAllowed) {\n  // hide translations editor; exclude from config save payload\n  return\n}","typeGuard":null,"tryCatchPattern":"try {\n  await configApi.save({ type: \"translations\", config })\n} catch (err) {\n  if (err.status === 403 && err.message.includes(\"translations\")) {\n    // show upgrade path; don't retry\n  } else { throw err }\n}","preventionTips":["Check the translations entitlement before rendering the editor","Exclude translations from saved payloads when unlicensed","Treat 403 on premium features as an entitlement issue, not a code bug","Re-check entitlements after license renewal or expiry"],"tags":["translations","licensing","entitlements","forbidden"],"backgroundTag":"license-feature-gated","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}