Budibase/budibase · error

JS invalid: ${message}

Error message

JS invalid: ${message}

What it means

After finding a datasource plugin's .js bundle, storePlugin compiles it inside an isolated-vm Isolate (compileScriptSync on Module.wrap(js)) as a sanity check. If the script fails to compile — a syntax error, unsupported syntax for the isolate, or a non-Error thrown value — the original error's message is rethrown prefixed with 'JS invalid: '. This stops broken plugin code from being stored and executed later.

Source

Thrown at packages/pro/src/sdk/plugins/index.ts:52

  const files = await objectStore.uploadDirectory(
    objectStore.ObjectStoreBuckets.PLUGINS,
    directory,
    bucketPath
  )
  const jsFile = files.find((file: any) => file.name.endsWith(".js"))
  const iconFile = files.find((file: any) => file.name.endsWith(".svg"))
  if (!jsFile) {
    throw new Error(`Plugin missing .js file.`)
  }
  // validate the JS for a datasource
  if (metadata.schema.type === PluginType.DATASOURCE) {
    const js = loadJSFile(directory, jsFile.name)
    const isolate = new ivm.Isolate({ memoryLimit: 8 })
    try {
      isolate.compileScriptSync(Module.wrap(js), { filename: jsFile.name })
    } catch (err: any) {
      const message = err?.message ? err.message : JSON.stringify(err)
      throw new Error(`JS invalid: ${message}`)
    } finally {
      isolate.dispose()
    }
  }
  const iconFileName = iconFile ? iconFile.name : null
  const pluginId = dbCore.generatePluginID(name)

  // overwrite existing docs entirely if they exist
  let rev
  try {
    const existing = await db.get<Plugin>(pluginId)
    rev = existing._rev
  } catch (err) {
    rev = undefined
  }
  let doc: Plugin = {
    _id: pluginId,
    _rev: rev,

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Open the reported file and fix the syntax error at the position given in the wrapped message
  2. Rebuild the plugin bundle with a bundler target compatible with the runtime's V8 version
  3. Validate the bundle locally with node --check before zipping and uploading
  4. Ensure the .js file is real JavaScript (not an HTML error page or truncated download) and re-upload

Example fix

// before: uploading a bundle with a syntax error (truncated file)
export default class MyDatasource { connect() {
// after: verify before upload
// after fixing
export default class MyDatasource { connect() { /* ... */ } }
Defensive patterns

Strategy: validation

Validate before calling

// validate locally before uploading
require("child_process").execSync(`node --check ${pluginJsFile}`)

Try / catch

try {
  storePluginFile(plugin)
} catch (err: any) {
  if (String(err.message).startsWith("JS invalid:")) {
    console.error("Plugin bundle failed isolate compile:", err.message)
  } else { throw err }
}

Prevention

When it happens

Trigger: Uploading a datasource plugin whose .js bundle contains a JavaScript syntax error; a bundle transpiled with syntax the isolate's V8 version cannot parse; loadJSFile returning garbage (e.g. minified HTML error page saved as .js).

Common situations: Plugin build produced a partial/corrupt bundle; author hand-edited the bundle; bundler target mismatch with the embedded V8 (isolated-vm) version; the .js file is actually a download error page from a proxy.

Related errors


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