angular/angular-cli · error · Error
Could not find the main bundle.
Error message
Could not find the main bundle.
What it means
After locating the server output directory, the app-shell builder scans it for a file matching /^main\.(?:[a-zA-Z0-9]{16}\.)?js$/ to use as the server module bundle for prerendering. If no such file exists, it throws. The server build produced output but not a bundle named main.js (or main.<hash>.js).
Source
Thrown at packages/angular_devkit/build_angular/src/builders/app-shell/index.ts:155
serverResult: ServerBuilderOutput,
browserLocaleDirectory: string,
) {
if (options.appModuleBundle) {
return path.join(context.workspaceRoot, options.appModuleBundle);
}
const { baseOutputPath = '' } = serverResult;
const outputPath = path.join(baseOutputPath, browserLocaleDirectory);
if (!fs.existsSync(outputPath)) {
throw new Error(`Could not find server output directory: ${outputPath}.`);
}
const re = /^main\.(?:[a-zA-Z0-9]{16}\.)?js$/;
const maybeMain = fs.readdirSync(outputPath).find((x) => re.test(x));
if (!maybeMain) {
throw new Error('Could not find the main bundle.');
}
return path.join(outputPath, maybeMain);
}
async function _appShellBuilder(
options: BuildWebpackAppShellSchema,
context: BuilderContext,
): Promise<BuilderOutput> {
context.logger.warn(
'The "@angular-devkit/build-angular:app-shell" builder is deprecated as part of Angular\'s Webpack support deprecation. ' +
'Use "@angular/build:application" instead. For more information, see https://angular.dev/tools/cli/build-system-migration.',
);
const browserTarget = targetFromTargetString(options.browserTarget);
const serverTarget = targetFromTargetString(options.serverTarget);
// Never run the browser target in watch mode.View on GitHub (pinned to bb72145f9a)
Solutions
- Ensure the server target emits a bundle named main.js (or main.<16-hex-hash>.js) directly in the server output directory.
- If using a custom webpack config, keep the 'main' entry/bundle name unchanged.
- If using the new application/esbuild server builder, use the app-shell/prerender support of '@angular/build' instead of the webpack app-shell builder, since output naming differs.
- Inspect the actual server output directory contents and fix outputPath configuration so it points at the folder containing the main bundle.
Example fix
// before (custom webpack config for server)
output: { filename: '[name].bundle.js' }
// after
output: { filename: '[name].js' } // emits main.js Defensive patterns
Strategy: validation
Validate before calling
import * as fs from 'fs';
const files = fs.readdirSync(serverOutputPath);
if (!files.some((f) => /^main\.(?:[a-zA-Z0-9]{16}\.)?js$/.test(f))) {
throw new Error(`No main.js bundle in ${serverOutputPath}: ${files.join(', ')}`);
} Type guard
const isMainBundle = (f: string) => /^main\.(?:[a-zA-Z0-9]{16}\.)?js$/.test(f); Try / catch
try {
await runAppShell();
} catch (e) {
if (String(e.message) === 'Could not find the main bundle.') {
// inspect server output naming, fix webpack output filename or builder choice
}
throw e;
} Prevention
- Do not rename the 'main' entry bundle in server webpack configs
- Match server builder output layout to what app-shell expects
- Verify server output directory contents after builds in CI
- Prefer @angular/build prerender support with the application builder
When it happens
Trigger: The server target was configured with a custom output filename/bundle name (e.g. bundleName set or webpack config renaming main), the server outputPath points at a folder containing nested folders instead of flat bundles, or a different builder (esbuild-based server builder producing different naming) is used as serverTarget.
Common situations: Custom webpack builder configs renaming entry bundles; swapping the universal/server target to '@angular/build:application' whose output layout (e.g. server.mjs, subdirectories) no longer matches the webpack-era main.js pattern expected here; poking around dist and moving files.
Related errors
- Could not find server output directory: ${outputPath}.
- Configuration error: found 'withAppShell()' without 'withRou
- Error(s) occurred while extracting routes:\n${errors.map((er
- Webpack stats build result is required.
- Unknown file requested: ${requestedPath}
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/5f8dc9227ad1fa26.
Report an issue: GitHub.