angular/angular-cli · error · Error

Could not find the main bundle: ${serverBundlePath}

Error message

Could not find the main bundle: ${serverBundlePath}

What it means

During prerendering, after the browser build completes, the prerender builder expects a corresponding server build's `main.js` bundle in the server output directory (per locale). This error is thrown in `_renderUniversal` when `main.js` cannot be found at the computed `serverBundlePath`, meaning the server bundle is missing or named differently. The library throws it because rendering routes requires loading the server bundle to execute Angular Universal.

Source

Thrown at packages/angular_devkit/build_angular/src/builders/prerender/index.ts:198

  const { baseOutputPath = '' } = serverResult;
  const worker = new Piscina({
    filename: path.join(__dirname, 'render-worker.js'),
    maxThreads: maxWorkers,
    workerData: { zonePackage },
    recordTiming: false,
  });

  let routes: string[] | undefined;

  try {
    // We need to render the routes for each locale from the browser output.
    for (const { path: outputPath } of browserResult.outputs) {
      const localeDirectory = path.relative(browserResult.baseOutputPath, outputPath);
      const serverBundlePath = path.join(baseOutputPath, localeDirectory, 'main.js');

      if (!fs.existsSync(serverBundlePath)) {
        throw new Error(`Could not find the main bundle: ${serverBundlePath}`);
      }

      routes ??= await getRoutes(
        indexFile,
        outputPath,
        serverBundlePath,
        options,
        context.workspaceRoot,
      );

      const spinner = ora(`Prerendering ${routes.length} route(s) to ${outputPath}...`).start();

      try {
        const results = (await Promise.all(
          routes.map((route) => {
            const options: RenderOptions = {
              indexFile,
              deployUrl: browserOptions.deployUrl || '',

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Run the server builder first (ng run <project>:server) and verify `main.js` exists in the server output directory.
  2. Ensure `prerender` target's `browserTarget` and `serverTarget` point at configurations whose outputPath matches and whose output is not hashed/renamed.
  3. Check the server tsconfig/webpack config for custom output filenames and restore `main.js` as the bundle name.
  4. Delete the output folder and rebuild both browser and server targets to rule out stale/corrupt output.

Example fix

// angular.json - prerender target pointing only at browser build
"options": { "browserTarget": "app:build" }
// after: include the server target output and default filenames
"options": { "browserTarget": "app:build", "serverTarget": "app:server" }
Defensive patterns

Strategy: validation

Validate before calling

import * as fs from 'fs';
import * as path from 'path';
const serverBundlePath = path.join(serverOutputPath, localeDir ?? '', 'main.js');
if (!fs.existsSync(serverBundlePath)) {
  throw new Error(`Run the server target first; missing bundle: ${serverBundlePath}`);
}

Prevention

When it happens

Trigger: Running `ng run <project>:prerender` (or dev-server with prerendering/SRG) where `fs.existsSync(serverBundlePath)` fails because the server build output does not contain `main.js` at `<server-output>/<locale-dir>/main.js`.

Common situations: The project's server builder output was renamed or the server tsconfig outputs a bundle under a different filename; the server build target was not built or was configured with a different outputPath; custom webpack configuration changes the output filename; cleaning the output directory removed the server bundle; upgrading Angular changed the server bundle filename (e.g. `main.js` vs hashed names).

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/bc0f58641419ab43. Report an issue: GitHub.