{"record":{"id":"62761af130b49508","repo":"Budibase/budibase","slug":"user-does-not-have-access-to-environment-variables","errorCode":null,"errorMessage":"User does not have access to environment variables feature.","messagePattern":"User does not have access to environment variables feature\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/pro/src/sdk/environmentVariables/environmentVariables.ts","lineNumber":40,"sourceCode":"  for (let [key, value] of Object.entries(decrypted)) {\n    switch (environment) {\n      case Environment.DEVELOPMENT:\n        output[key] = value.development\n        break\n      case Environment.PRODUCTION:\n      default:\n        output[key] = value.production\n        break\n    }\n  }\n  return output\n}\n\nasync function changeValues(cb: (values: VariableMap) => VariableMap) {\n  // only block access when updating values, let users fetch\n  const license = await licensing.cache.getCachedLicense()\n  if (!license.features.includes(Feature.ENVIRONMENT_VARIABLES)) {\n    throw new Error(\n      \"User does not have access to environment variables feature.\"\n    )\n  }\n  const doc = await environmentVariables.get()\n  doc.variables = cb(doc.variables)\n  await environmentVariables.update(doc)\n}\n\nexport async function update(varName: string, value: EnvironmentVariableValue) {\n  const checkName = isValid(varName)\n  if (checkName) {\n    await changeValues(values => {\n      values[varName] = value\n      return values\n    })\n  } else {\n    throw new Error(\"Variable name has characters that are not allowed\")\n  }","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/pro/src/sdk/environmentVariables/environmentVariables.ts#L22-L58","documentation":"Environment variables are a licensed Budibase Pro feature. changeValues loads the tenant's cached license and throws if the license does not include Feature.ENVIRONMENT_VARIABLES before it will apply any mutation to the variable map. Reads are allowed, but updates/removals are blocked without the entitlement.","triggerScenarios":"Calling update() or remove() (both of which call changeValues) when the tenant's cached license from licensing.cache.getCachedLicense() does not list Feature.ENVIRONMENT_VARIABLES in its features array.","commonSituations":"Running on the free/open-source plan without a Pro license or trial; a self-hosted activation where the license key was not applied to the tenant; a stale license cache after downgrading the plan.","solutions":["Upgrade the tenant to a license that includes the environment variables feature (Pro/Enterprise) or start a trial.","Apply/refresh the license key so licensing.cache picks up the feature, then clear/renew the cached license.","If you believe the license includes the feature, force a license re-fetch to fix a stale cache and retry.","Restructure the workflow to avoid environment variables if staying on an unlicensed plan."],"exampleFix":"// before\nawait environmentVariables.update(\"API_KEY\", \"secret\") // throws on free plan\n// after\nconst license = await licensing.cache.getCachedLicense()\nif (license.features.includes(Feature.ENVIRONMENT_VARIABLES)) {\n  await environmentVariables.update(\"API_KEY\", \"secret\")\n}","handlingStrategy":"try-catch","validationCode":"const license = await licensing.cache.getCachedLicense()\nconst canUseEnvVars = license.features.includes(Feature.ENVIRONMENT_VARIABLES)","typeGuard":"function hasEnvVarFeature(license: License): boolean {\n  return license.features.includes(Feature.ENVIRONMENT_VARIABLES)\n}","tryCatchPattern":"try {\n  await environmentVariables.update(name, value)\n} catch (err) {\n  if (err.message.includes(\"environment variables feature\")) {\n    // show plan-upgrade prompt or disable the feature\n  } else throw err\n}","preventionTips":["Check license features in the UI before exposing env-var editing","Ensure the license key is applied and the license cache is refreshed after upgrades","Gate writes behind a feature check; leave reads unguarded like the SDK does"],"tags":["licensing","feature-flag","environment-variables"],"backgroundTag":"license-feature-missing","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}