vuejs/vue · error · Error

bundle export should be a function when using { runInNewCont

Error message

bundle export should be a function when using { runInNewContext: false }.

What it means

Thrown by createBundleRunner when runInNewContext is false (or 'once') and the bundle's entry export, after evaluation, is not a function. In direct mode (runInNewContext: false) the runner is evaluated once and then invoked as runner(userContext) on every render — so the export must be a callable function. In new-context mode the export is allowed to be a component object because the whole bundle re-evaluates each render.

Source

Thrown at packages/server-renderer/src/bundle-renderer/create-bundle-runner.ts:127

    // module evaluation costs but requires the source code to be structured
    // slightly differently.
    let runner // lazy creation so that errors can be caught by user
    let initialContext
    return (userContext = {}) =>
      new Promise(resolve => {
        if (!runner) {
          const sandbox = runInNewContext === 'once' ? createSandbox() : global
          // the initial context is only used for collecting possible non-component
          // styles injected by vue-style-loader.
          // @ts-expect-error
          initialContext = sandbox.__VUE_SSR_CONTEXT__ = {}
          runner = evaluate(entry, sandbox)
          // On subsequent renders, __VUE_SSR_CONTEXT__ will not be available
          // to prevent cross-request pollution.
          // @ts-expect-error
          delete sandbox.__VUE_SSR_CONTEXT__
          if (typeof runner !== 'function') {
            throw new Error(
              'bundle export should be a function when using ' +
                '{ runInNewContext: false }.'
            )
          }
        }
        // @ts-expect-error
        userContext._registeredComponents = new Set()

        // vue-style-loader styles imported outside of component lifecycle hooks
        if (initialContext._styles) {
          // @ts-expect-error
          userContext._styles = deepClone(initialContext._styles)
          // #6353 ensure "styles" is exposed even if no styles are injected
          // in component lifecycles.
          // the renderStyles fn is exposed by vue-style-loader >= 3.0.3
          const renderStyles = initialContext._renderStyles
          if (renderStyles) {
            Object.defineProperty(userContext, 'styles', {

View on GitHub (pinned to 9e88707940)

Solutions

  1. Set webpack output.libraryTarget to 'commonjs2' so the entry exports a callable function.
  2. Ensure the SSR entry exports a function: `export default context => { /* create app, return app or promise */ }`.
  3. If the bundle cannot be restructured, use runInNewContext: true (default) which accepts an object export.
  4. Verify the built bundle's last line: with commonjs2 it should be module.exports = function (...) {...}.

Example fix

// before — entry exports an object, fails with runInNewContext: false
export default new Vue({ ... })

// after — entry exports a function
export default context => {
  return new Promise((resolve, reject) => {
    const app = new Vue({ ... })
    resolve(app)
  })
}
Defensive patterns

Strategy: validation

Validate before calling

function assertBundleExportsFunction(entryPath: string): boolean {
  // inspect the built bundle: with commonjs2, the last export should be a function
  const src = fs.readFileSync(entryPath, 'utf-8')
  // crude heuristic: module.exports = function or exports.default = function
  return /module\.exports\s*=\s*function/.test(src) || /exports\.default\s*=\s*function/.test(src)
}

if (runInNewContext === false && !assertBundleExportsFunction(entryPath)) {
  throw new Error('SSR entry must export a function when runInNewContext is false')
}

Type guard

// Runtime check after evaluation
function isFunctionRunner(runner: unknown): runner is (ctx: any) => any {
  return typeof runner === 'function'
}

Try / catch

// The error is thrown inside the promise chain of run(context).
// Catch at the render call:
renderer.renderToString(context, (err, html) => {
  if (err && err.message.includes('bundle export should be a function')) {
    console.error('Fix webpack output.libraryTarget=commonjs2 and export a function from entry-server.js')
  }
})

Prevention

When it happens

Trigger: Building an SSR bundle with output.libraryTarget set to var/jsonp or omitting commonjs2, so the entry module exports an object (the app factory) instead of a function. Also triggered by a bundle that does `export default { ... }` rather than `export default () => { ... }`.

Common situations: Webpack server config output.libraryTarget is not commonjs2. The entry file's default export is the app instance or options object rather than a function that creates the app. Switching from runInNewContext: true to false without restructuring the entry.

Related errors


AI-assisted analysis of vuejs/vue@9e88707940 (2026-08-11). Data as JSON: /api/errors/0b32ef1cdf891bef. Report an issue: GitHub.