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 fundamentalView on GitHub (pinned to a81a902e9a)
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.
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
- 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
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
- CLOUDFRONT_PRIVATE_KEY_64 is not set
- Logging disabled for backend bindings
- Workspace DB not found - self-host users using cloud don't h
- CouchDB username not set
- CouchDB password not set
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/337e0d8b352077df.
Report an issue: GitHub.