{"record":{"id":"92744786e5179378","repo":"vuejs/vue","slug":"invalid-json-bundle-file-bundle","errorCode":null,"errorMessage":"Invalid JSON bundle file: ${bundle}","messagePattern":"Invalid JSON bundle file: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server-renderer/src/bundle-renderer/create-bundle-renderer.ts","lineNumber":57,"sourceCode":"    let files, entry, maps\n    let basedir = rendererOptions.basedir\n\n    // load bundle if given filepath\n    if (\n      typeof bundle === 'string' &&\n      /\\.js(on)?$/.test(bundle) &&\n      path.isAbsolute(bundle)\n    ) {\n      if (fs.existsSync(bundle)) {\n        const isJSON = /\\.json$/.test(bundle)\n        basedir = basedir || path.dirname(bundle)\n        bundle = fs.readFileSync(bundle, 'utf-8')\n        if (isJSON) {\n          try {\n            // @ts-expect-error\n            bundle = JSON.parse(bundle)\n          } catch (e: any) {\n            throw new Error(`Invalid JSON bundle file: ${bundle}`)\n          }\n        }\n      } else {\n        throw new Error(`Cannot locate bundle file: ${bundle}`)\n      }\n    }\n\n    if (typeof bundle === 'object') {\n      entry = bundle.entry\n      files = bundle.files\n      basedir = basedir || bundle.basedir\n      maps = createSourceMapConsumers(bundle.maps)\n      if (typeof entry !== 'string' || typeof files !== 'object') {\n        throw new Error(INVALID_MSG)\n      }\n    } else if (typeof bundle === 'string') {\n      entry = '__vue_ssr_bundle__'\n      files = { __vue_ssr_bundle__: bundle }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/vuejs/vue/blob/9e88707940088cb1f4cd7dd210c9168a50dc347c/packages/server-renderer/src/bundle-renderer/create-bundle-renderer.ts#L39-L75","documentation":"Thrown by createBundleRenderer when an absolute .json bundle path is read from disk but JSON.parse fails. The bundle argument was reassigned to the raw file contents before parsing, so the error message shows the (potentially large) raw string rather than the path. This indicates the JSON manifest produced by vue-ssr-webpack-plugin or a custom pipeline is corrupt or not valid JSON.","triggerScenarios":"Calling createBundleRenderer('/abs/path/to/vue-ssr-server-bundle.json') where the file exists but is malformed JSON — truncated, contains BOM, has trailing commas, was partially written, or is actually a JS bundle mislabeled .json.","commonSituations":"A build job was killed mid-write leaving a truncated JSON file. A CI cache served a stale/corrupt manifest. The .json extension was mistakenly applied to a raw JS bundle string. Manual edits to the generated manifest introduced invalid syntax.","solutions":["Regenerate the bundle manifest by re-running the webpack SSR build with VueSSRServerPlugin.","Validate the file with `node -e \"JSON.parse(require('fs').readFileSync('path','utf-8'))\"` to confirm it is parseable.","If the file is a raw JS bundle (single file), pass it with a .js extension instead of .json, or pass the manifest object directly.","Check for truncation: compare file size against a known-good build or re-emit from a clean build directory."],"exampleFix":"// before — file is corrupt/truncated JSON\ncreateBundleRenderer('/app/dist/vue-ssr-server-bundle.json')\n\n// after — regenerate manifest then load, or load object directly\nconst bundle = require('/app/dist/vue-ssr-server-bundle.json')\ncreateBundleRenderer(bundle)","handlingStrategy":"validation","validationCode":"import * as fs from 'fs'\n\nfunction isValidJsonBundle(path: string): boolean {\n  if (!fs.existsSync(path)) return false\n  try {\n    const obj = JSON.parse(fs.readFileSync(path, 'utf-8'))\n    return typeof obj === 'object' && obj !== null && typeof obj.entry === 'string'\n  } catch {\n    return false\n  }\n}\n\nif (!isValidJsonBundle(bundlePath)) {\n  throw new Error(`${bundlePath} is not a valid SSR bundle JSON; rebuild it.`)\n}\ncreateBundleRenderer(bundlePath)","typeGuard":"function isRenderBundle(v: unknown): v is { entry: string; files: Record<string,string>; maps?: Record<string,string> } {\n  if (typeof v !== 'object' || v === null) return false\n  const o = v as any\n  return typeof o.entry === 'string' && typeof o.files === 'object'\n}","tryCatchPattern":"try {\n  createBundleRenderer(bundlePath)\n} catch (e) {\n  if (e.message.startsWith('Invalid JSON bundle file')) {\n    // delete corrupt artifact and trigger rebuild\n    fs.unlinkSync(bundlePath)\n    await rebuildSSRBundle()\n  }\n  throw e\n}","preventionTips":["Never hand-edit generated SSR bundle manifests.","In CI, fail the build if the manifest JSON cannot be parsed after emission.","Treat the manifest as a build artifact: regenerate from source rather than mutating on disk.","Write manifests atomically (temp file + rename) to avoid truncation on killed builds."],"tags":["ssr","bundle-renderer","json","filesystem","validation"],"analyzedSha":"9e88707940088cb1f4cd7dd210c9168a50dc347c","analyzedAt":"2026-08-11T22:22:01.295Z","schemaVersion":2},"datasetVersion":"2026-08-12T04:17:13.124Z"}