Budibase/budibase · error · UserScriptError
result.error
Error message
result.error
What it means
User scripts run in a sandboxed JS context via jsSandbox.runInNewContext. The sandbox captures runtime errors instead of throwing natively, returning them as result.error. string-templates wraps that value in a UserScriptError so the caller sees the script's own failure message.
Source
Thrown at packages/string-templates/src/index.ts:743
}
js += "`;"
return `${varBlock}${js}`
}
export { JsTimeoutError, UserScriptError } from "./errors"
export function browserJSSetup() {
// tests are in jest - we need to use node VM for these
const jsSandbox = isTest() ? vm : browserVM
// Use polyfilled vm to run JS scripts in a browser Env
setJSRunner((js: string, context: Record<string, any>) => {
jsSandbox.createContext(context)
const wrappedJs = frontendWrapJS(js)
const result = jsSandbox.runInNewContext(wrappedJs, context)
if (result.error) {
throw new UserScriptError(result.error)
}
return result.result
})
}
export function defaultJSSetup() {
if (!isBackendService()) {
browserJSSetup()
} else {
removeJSRunner()
}
}
defaultJSSetup()
View on GitHub (pinned to a81a902e9a)
Solutions
- Read the UserScriptError message to find the failing line/identifier in the script
- Fix the script: guard against null/undefined inputs before use
- Verify every referenced helper/variable exists in the sandbox context (defaultJSSetup provides the available helpers)
- Reproduce the expression with sample data to confirm the fix before deploying
Example fix
// before return data.row.someField.toUpperCase() // after return data.row?.someField ? data.row.someField.toUpperCase() : ""
Defensive patterns
Strategy: try-catch
Validate before calling
// before evaluating
function validateScriptUsable(js: string, ctxKeys: string[]) {
if (!js || !js.trim()) throw new Error("Empty script")
// optionally regex-scan for identifiers not present in ctxKeys
} Type guard
function hasScriptError(r: { error?: unknown; result?: unknown }): r is { error: unknown } {
return r != null && r.error != null
} Try / catch
try {
const out = await processString(js)
} catch (err) {
if (err instanceof UserScriptError) {
// surface err.message to the user as a script-authoring problem
} else { throw err }
} Prevention
- Guard null/undefined data inside the script before use
- Only reference helpers provided by the sandbox context (defaultJSSetup)
- Test bindings with empty/edge-case data at design time
- Keep scripts small and single-purpose so failures are easy to localize
When it happens
Trigger: A JS binding/script evaluated at runtime throws inside the sandbox: referencing an undefined variable, calling a non-existent method, throwing explicitly, or an unhandled runtime error during execution.
Common situations: App builders write JS bindings with typos, use APIs that don't exist in the sandbox context, or scripts that assume data present at design time but absent at render time (e.g. a row field is null).
Related errors
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/75d92224db3c14c3.
Report an issue: GitHub.