{"record":{"id":"a9be18e547ef605d","repo":"Budibase/budibase","slug":"invalid-license-key","errorCode":null,"errorMessage":"Invalid license key","messagePattern":"Invalid license key","errorType":"exception","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/pro/src/sdk/licensing/licenses/client.ts","lineNumber":239,"sourceCode":"  licenseKey: string\n): Promise<License | undefined> => {\n  const install = await installation.getInstall()\n\n  const body: LicenseActivateRequest = {\n    installVersion: install.version,\n    installId: install.installId,\n  }\n\n  const response = await api.post(`/api/license/activate`, {\n    headers: {\n      [constants.Header.LICENSE_KEY]: licenseKey,\n    },\n    body,\n  })\n\n  // don't propagate the 403 to prevent logout\n  if (response.status === 403) {\n    throw new HTTPError(\"Invalid license key\", 400)\n  }\n\n  if (response.status === 409) {\n    throw new HTTPError(\"License key has already been activated\", 409)\n  }\n\n  if (response.status !== 200) {\n    const message = await getResponseErrorMessage(response)\n    throw new HTTPError(\n      `Error activating license key: ${message}`,\n      response.status\n    )\n  }\n\n  return response.json()\n}\n","sourceCodeStart":221,"sourceCodeEnd":256,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/pro/src/sdk/licensing/licenses/client.ts#L221-L256","documentation":"Thrown by activateLicenseKey when POST /api/license/activate responds with 403, meaning the account portal rejected the license key as invalid. The library deliberately converts the 403 to a 400 so the caller is not logged out by generic 403 handling. It signals the key itself is not recognized/entitled, not a transport or server failure.","triggerScenarios":"Calling activateLicenseKey(licenseKey) with a key the account portal does not recognize, a key that was revoked, or a key from a different environment — the portal returns 403 for the activation request.","commonSituations":"Typo'd or truncated license key pasted into self-host activation UI; key for a cloud tenant used on a self-host install; license cancelled on the account portal; pointing the install at the wrong account portal URL so the key is unknown there.","solutions":["Double-check the license key for typos/truncation and re-enter it exactly as issued.","Confirm the key belongs to this installation type/environment and the account portal URL (INTERNAL_ACCOUNT_PORTAL_URL / ACCOUNT_PORTAL_URL) matches where the key was issued.","Verify the license is still active (not cancelled/expired) in the account portal.","If the key is valid but still rejected, contact Budibase support with the key and install details."],"exampleFix":"// before\nawait activateLicenseKey(userInput.trim())\n// after\nif (!userInput || userInput.trim().length === 0) {\n  throw new Error(\"License key is required\")\n}\nawait activateLicenseKey(userInput.trim())","handlingStrategy":"validation","validationCode":"function isValidKeyFormat(key: string): boolean {\n  return typeof key === \"string\" && key.trim().length > 0 && /^[A-Za-z0-9-_]+$/.test(key.trim())\n}\nif (!isValidKeyFormat(userKey)) throw new Error(\"License key format looks invalid\")","typeGuard":"function isHTTPError(e: unknown): e is HTTPError {\n  return e instanceof HTTPError\n}","tryCatchPattern":"try {\n  await activateLicenseKey(key)\n} catch (e) {\n  if (isHTTPError(e) && e.status === 400) {\n    // show 'license key invalid — check key and environment' to the user\n  } else throw e\n}","preventionTips":["Trim and normalize license keys before activation.","Use a dedicated license key per environment; never share keys between installs.","Verify the portal URL env vars point at the same portal that issued the key.","Confirm the license is active in the account portal before activation attempts."],"tags":["licensing","activation","invalid-license-key","http-error"],"backgroundTag":"invalid-license-key","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}