{"record":{"id":"337e0d8b352077df","repo":"Budibase/budibase","slug":"js-disabled-in-environment","errorCode":null,"errorMessage":"JS disabled in environment.","messagePattern":"JS disabled in environment\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/string-templates/src/helpers/javascript.ts","lineNumber":74,"sourceCode":"  let data = context\n  // check if it's a literal string - just return path if its quoted\n  if (literalStringRegex.test(path)) {\n    return path.substring(1, path.length - 1)\n  }\n  path.split(\".\").forEach(key => {\n    if (data == null || typeof data !== \"object\") {\n      return null\n    }\n    data = data[removeSquareBrackets(key)]\n  })\n\n  return data\n}\n\n// Evaluates JS code against a certain context\nexport function processJS(handlebars: string, context: any) {\n  if (!isJSAllowed() || !runJS) {\n    throw new Error(\"JS disabled in environment.\")\n  }\n  try {\n    // Wrap JS in a function and immediately invoke it.\n    // This is required to allow the final `return` statement to be valid.\n    const js = iifeWrapper(atob(handlebars))\n\n    // Transform snippets into an object for faster access, and cache previously\n    // evaluated snippets\n    let snippetMap: any = {}\n    let snippetCache: any = {}\n    for (let snippet of context.snippets || []) {\n      snippetMap[snippet.name] = snippet.code\n    }\n\n    let clonedContext: Record<string, any>\n    if (isBackendService()) {\n      // On the backend, values are copied across the isolated-vm boundary and\n      // so we don't need to do any cloning here. This does create a fundamental","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/string-templates/src/helpers/javascript.ts#L56-L92","documentation":"processJS in packages/string-templates/src/helpers/javascript.ts evaluates JS bindings inside Handlebars templates. It first checks isJSAllowed() (true unless the NO_JS environment variable is set) and that the runJS implementation is available; if either fails it throws \"JS disabled in environment.\". Budibase can run with JS bindings disabled as a security hardening option, and some bundles may not include the JS runner.","triggerScenarios":"Rendering a template containing a {{ js ... }} binding while the NO_JS env var is set, or in a build/runtime where runJS is undefined (e.g. certain server/worker contexts or builds without the JS helper wired in).","commonSituations":"Self-hosted deployments with NO_JS=true for sandboxing; apps created where JS bindings were used but the hosting environment disables them; running string-templates in a bundled environment where the runJS module wasn't included; automated previews/exports with JS disabled.","solutions":["Remove/unset the NO_JS environment variable for the process rendering the template.","Replace the JS binding with a pure Handlebars helper or precompute the value in the context.","Ensure you're using a build of string-templates that includes the runJS helper (default bundled builds do).","Check the deployment environment config to confirm whether JS bindings are intentionally disabled."],"exampleFix":"// before (render env)\nNO_JS=1 yarn dev\n// after\nunset NO_JS && yarn dev  // or remove JS bindings from the template","handlingStrategy":"try-catch","validationCode":"function canProcessJS() {\n  return process.env.NO_JS == null // mirror of isJSAllowed()\n}\nif (!canProcessJS()) {\n  console.warn(\"JS bindings disabled — stripping js helpers from template\")\n}","typeGuard":null,"tryCatchPattern":"let rendered: string\ntry {\n  rendered = processString(template, context)\n} catch (e) {\n  if (e.message === \"JS disabled in environment.\") {\n    rendered = processString(stripJsBindings(template), context)\n  } else throw e\n}","preventionTips":["Check whether NO_JS is set in the target environment before shipping templates with JS bindings","Prefer pure Handlebars helpers over JS bindings for portability","Precompute JS-binding results into the context when rendering server-side","Document the NO_JS hardening flag in deployment configs so teams know its effect"],"tags":["environment","javascript","bindings","configuration"],"backgroundTag":"js-bindings-disabled","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}