vuejs/vue · error · Error

Invalid server-rendering bundle format. Should be a string o

Error message

Invalid server-rendering bundle format. Should be a string or a bundle Object of type:\n\n{
  entry: string;
  files: { [filename: string]: string; };
  maps: { [filename: string]: string; };
}

What it means

Thrown when the bundle is an object but its shape is wrong: either bundle.entry is not a string, or bundle.files is not an object. createBundleRenderer expects a RenderBundle of type { entry: string; files: { [name]: string }; maps: { [name]: string }; basedir? }. This guard fires after the object has already been destructured, so a missing entry key (undefined) or a files value that is an array/string triggers it.

Source

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

          try {
            // @ts-expect-error
            bundle = JSON.parse(bundle)
          } catch (e: any) {
            throw new Error(`Invalid JSON bundle file: ${bundle}`)
          }
        }
      } else {
        throw new Error(`Cannot locate bundle file: ${bundle}`)
      }
    }

    if (typeof bundle === 'object') {
      entry = bundle.entry
      files = bundle.files
      basedir = basedir || bundle.basedir
      maps = createSourceMapConsumers(bundle.maps)
      if (typeof entry !== 'string' || typeof files !== 'object') {
        throw new Error(INVALID_MSG)
      }
    } else if (typeof bundle === 'string') {
      entry = '__vue_ssr_bundle__'
      files = { __vue_ssr_bundle__: bundle }
      maps = {}
    } else {
      throw new Error(INVALID_MSG)
    }

    const renderer = createRenderer(rendererOptions)

    const run = createBundleRunner(
      entry,
      files,
      basedir,
      rendererOptions.runInNewContext
    )

View on GitHub (pinned to 9e88707940)

Solutions

  1. Ensure the object has entry (string), files (object of filename->content strings), and maps (object).
  2. Load the server bundle JSON produced by VueSSRServerPlugin, not the client manifest.
  3. If passing a single bundled JS string, pass it as a string argument instead of wrapping it incorrectly in an object.
  4. Inspect the object with console.log(Object.keys(bundle)) to verify the expected keys exist.

Example fix

// before — wrong object shape
createBundleRenderer({ entries: 'main.js', files: ['main.js'] })

// after — correct RenderBundle
createBundleRenderer({
  entry: 'main.js',
  files: { 'main.js': bundleSourceString },
  maps: {}
})
Defensive patterns

Strategy: type-guard

Validate before calling

function assertRenderBundleShape(bundle: unknown): void {
  if (typeof bundle !== 'object' || bundle === null) {
    throw new Error('bundle must be an object')
  }
  const b = bundle as any
  if (typeof b.entry !== 'string') throw new Error('bundle.entry must be a string')
  if (typeof b.files !== 'object' || b.files === null) throw new Error('bundle.files must be an object')
}

assertRenderBundleShape(bundle)
createBundleRenderer(bundle)

Type guard

type RenderBundle = { entry: string; files: Record<string, string>; maps?: Record<string, string>; basedir?: string }

function isRenderBundle(v: unknown): v is RenderBundle {
  if (typeof v !== 'object' || v === null) return false
  const o = v as Record<string, unknown>
  return typeof o.entry === 'string' && typeof o.files === 'object' && o.files !== null
}

Try / catch

try {
  createBundleRenderer(bundle)
} catch (e) {
  if (e.message.includes('Invalid server-rendering bundle format')) {
    console.error('Bundle shape invalid. Keys:', Object.keys(bundle || {}))
  }
  throw e
}

Prevention

When it happens

Trigger: Passing a hand-built object missing the entry property, with entry set to a number, or with files as an array or string instead of a key-value map. Also fires if the JSON manifest from a non-standard or older webpack plugin has a different schema.

Common situations: Loading a client manifest (vue-ssr-client-manifest.json) into createBundleRenderer instead of the server bundle. Passing a raw webpack stats object. Constructing a bundle object manually with a typo in the key name (e.g. entries instead of entry).

Related errors


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