{"record":{"id":"181dc3785405ec5d","repo":"Budibase/budibase","slug":"license-not-found-for-tenant-id-tenantid","errorCode":null,"errorMessage":"License not found for tenant id ${tenantId}","messagePattern":"License not found for tenant id (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/pro/src/sdk/quotas/quotas.ts","lineNumber":463,"sourceCode":"        opts: { ...action.opts, tenantId },\n      }))\n\n    if (usageQuotas.length > 0) {\n      await db.quotas.setAllUsage(usageQuotas)\n    }\n  })\n}\n\nexport const getLicensedQuota = async (\n  quotaType: QuotaType,\n  name: MonthlyQuotaName | StaticQuotaName | ConstantQuotaName,\n  usageType?: QuotaUsageType\n): Promise<Quota> => {\n  const license = await licensing.cache.getCachedLicense()\n\n  if (!license) {\n    const tenantId = tenancy.getTenantId()\n    throw new Error(\"License not found for tenant id \" + tenantId)\n  }\n\n  if (usageType && isStaticQuota(quotaType, usageType, name)) {\n    return license.quotas[quotaType as QuotaType.USAGE][\n      usageType as QuotaUsageType.STATIC\n    ][name]\n  } else if (usageType && isMonthlyQuota(quotaType, usageType, name)) {\n    return license.quotas[quotaType as QuotaType.USAGE][\n      usageType as QuotaUsageType.MONTHLY\n    ][name]\n  } else if (isConstantQuota(quotaType, name)) {\n    return license.quotas[quotaType as QuotaType.CONSTANT][name]\n  } else {\n    throw new Error(\"Invalid quota type\")\n  }\n}\n\nexport const usageLimitIsExceeded = async ({","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/pro/src/sdk/quotas/quotas.ts#L445-L481","documentation":"getLicensedQuota resolves quota values from the tenant's license, which is obtained through the licensing cache. If no license is present in the cache for the tenant (getTenantId()), it cannot resolve any quota and throws with the tenant id embedded for diagnostics. Quota checks are meaningless without a license, so the function fails fast.","triggerScenarios":"updateUsage or any quota resolution runs for a tenantId whose license is not in the licensing cache — license never activated, license fetch from licensing service failed, or the cache was cleared/expired and rehydration failed.","commonSituations":"Self-hosted install without an active license key attempting quota-gated operations; licensing service outage or network failure preventing license hydration into cache; tenant id mismatch (requesting quotas under a tenant that has no license record); Redis cache flush without license re-fetch.","solutions":["Activate/re-upload a valid license for the tenant so getCachedLicense() can hydrate","Verify connectivity to the licensing service and force a license cache refresh, then retry","Confirm the tenantId is correct (log/compare with the id in the error message)","Check Redis/licensing cache health; restart the cache rehydration if the license exists but isn't cached"],"exampleFix":"// before: quota updates before the license is activated\nawait quotas.tryIncrement({ name: MonthlyQuotaName.ROWS, usageChange: 1 })\n// after: ensure a license exists first\nconst license = await licensing.cache.getCachedLicense()\nif (!license) {\n  await activateLicense(licenseKey)\n}\nawait quotas.tryIncrement({ name: MonthlyQuotaName.ROWS, usageChange: 1 })","handlingStrategy":"validation","validationCode":"const license = await licensing.cache.getCachedLicense()\nif (!license) throw new Error(`Activate a license for tenant ${tenancy.getTenantId()} before quota operations`)","typeGuard":"function isLicenseMissing(err: unknown): boolean {\n  return err instanceof Error && err.message.startsWith(\"License not found for tenant id\")\n}","tryCatchPattern":"try {\n  await updateUsage(action)\n} catch (err) {\n  if (isLicenseMissing(err)) {\n    // trigger license activation / cache rehydration, then retry once\n  } else { throw err }\n}","preventionTips":["Activate a license before enabling quota-gated features","Monitor licensing service connectivity and cache health","Log tenantId alongside license errors to catch mismatches early"],"tags":["licensing","cache","quotas","tenant"],"backgroundTag":"license-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}