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

  1. Read the UserScriptError message to find the failing line/identifier in the script
  2. Fix the script: guard against null/undefined inputs before use
  3. Verify every referenced helper/variable exists in the sandbox context (defaultJSSetup provides the available helpers)
  4. 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

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.