Budibase/budibase · error

JS disabled in environment.

Error message

JS disabled in environment.

What it means

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.

Source

Thrown at packages/string-templates/src/helpers/javascript.ts:74

  let data = context
  // check if it's a literal string - just return path if its quoted
  if (literalStringRegex.test(path)) {
    return path.substring(1, path.length - 1)
  }
  path.split(".").forEach(key => {
    if (data == null || typeof data !== "object") {
      return null
    }
    data = data[removeSquareBrackets(key)]
  })

  return data
}

// Evaluates JS code against a certain context
export function processJS(handlebars: string, context: any) {
  if (!isJSAllowed() || !runJS) {
    throw new Error("JS disabled in environment.")
  }
  try {
    // Wrap JS in a function and immediately invoke it.
    // This is required to allow the final `return` statement to be valid.
    const js = iifeWrapper(atob(handlebars))

    // Transform snippets into an object for faster access, and cache previously
    // evaluated snippets
    let snippetMap: any = {}
    let snippetCache: any = {}
    for (let snippet of context.snippets || []) {
      snippetMap[snippet.name] = snippet.code
    }

    let clonedContext: Record<string, any>
    if (isBackendService()) {
      // On the backend, values are copied across the isolated-vm boundary and
      // so we don't need to do any cloning here. This does create a fundamental

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Remove/unset the NO_JS environment variable for the process rendering the template.
  2. Replace the JS binding with a pure Handlebars helper or precompute the value in the context.
  3. Ensure you're using a build of string-templates that includes the runJS helper (default bundled builds do).
  4. Check the deployment environment config to confirm whether JS bindings are intentionally disabled.

Example fix

// before (render env)
NO_JS=1 yarn dev
// after
unset NO_JS && yarn dev  // or remove JS bindings from the template
Defensive patterns

Strategy: try-catch

Validate before calling

function canProcessJS() {
  return process.env.NO_JS == null // mirror of isJSAllowed()
}
if (!canProcessJS()) {
  console.warn("JS bindings disabled — stripping js helpers from template")
}

Try / catch

let rendered: string
try {
  rendered = processString(template, context)
} catch (e) {
  if (e.message === "JS disabled in environment.") {
    rendered = processString(stripJsBindings(template), context)
  } else throw e
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/337e0d8b352077df. Report an issue: GitHub.