{"record":{"id":"0fdce636f57fa8f4","repo":"angular/angular-cli","slug":"a-module-or-bootstrap-option-must-be-provided","errorCode":null,"errorMessage":"A module or bootstrap option must be provided.","messagePattern":"A module or bootstrap option must be provided\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular/ssr/node/src/common-engine/common-engine.ts","lineNumber":190,"sourceCode":"      return undefined;\n    }\n\n    // Static file exists.\n    const content = await fs.promises.readFile(pagePath, 'utf-8');\n    const isSSG = SSG_MARKER_REGEXP.test(content);\n    if (isSSG) {\n      this.pageIsSSG.set(pagePath, true);\n\n      return content;\n    }\n\n    return undefined;\n  }\n\n  private async renderApplication(opts: CommonEngineRenderOptions): Promise<string> {\n    const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;\n    if (!moduleOrFactory) {\n      throw new Error('A module or bootstrap option must be provided.');\n    }\n\n    const extraProviders: StaticProvider[] = [\n      { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },\n      ...(opts.providers ?? []),\n      ...(this.options?.providers ?? []),\n    ];\n\n    let document = opts.document;\n    if (!document && opts.documentFilePath) {\n      document = await this.getDocument(opts.documentFilePath);\n    }\n\n    const commonRenderingOptions = {\n      url: opts.url,\n      document,\n      // Validation is already happened in the render method.\n      allowedHosts: ['*'],","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/ssr/node/src/common-engine/common-engine.ts#L172-L208","documentation":"CommonEngine.renderApplication needs an Angular module or bootstrap function to render the app server-side. If neither 'bootstrap' in the CommonEngineRenderOptions nor a bootstrap in the engine options is provided, rendering cannot proceed and an Error is thrown.","triggerScenarios":"Calling new CommonEngine().render(...) or renderApplication(...) without passing { bootstrap } in options, or a server.ts where the bootstrap option was removed/renamed during SSR migration.","commonSituations":"Upgrading Angular SSR versions where the option moved, hand-written server.ts missing the bootstrap export, custom SSR setups passing only template/providers.","solutions":["Pass bootstrap to CommonEngine options: new CommonEngine(AppServerModule, opts) or render({ bootstrap: AppServerModule })","In Angular 17+ SSR setups, pass the bootstrap function from app.config.server: { bootstrap: bootstrapApplication } pattern per docs","Check server.ts matches the generated template from ng add @angular/ssr","Verify the imported AppServerModule is not undefined due to a bad import path"],"exampleFix":"// before\nconst engine = new CommonEngine();\nexport const reqHandler = engine.getHandler({ });\n// after\nimport { AppServerModule } from './src/main.server';\nconst engine = new CommonEngine();\nexport const reqHandler = engine.getHandler({ bootstrap: AppServerModule });","handlingStrategy":"validation","validationCode":"import { AppServerModule } from './src/main.server';\nif (!AppServerModule) {\n  throw new Error('main.server export missing; fix import before creating CommonEngine');\n}\nconst engine = new CommonEngine();\nexport const reqHandler = engine.getHandler({ bootstrap: AppServerModule });","typeGuard":"function hasBootstrap(o: Partial<{ bootstrap: unknown }>): o is { bootstrap: NonNullable<unknown> } {\n  return o.bootstrap != null;\n}","tryCatchPattern":"try {\n  html = await engine.render({ bootstrap: AppServerModule, ...opts });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('A module or bootstrap option must be provided')) {\n    console.error('CommonEngine options must include bootstrap: AppServerModule');\n  }\n  throw e;\n}","preventionTips":["Copy server.ts from the ng add @angular/ssr generated template","Verify AppServerModule import path resolves (no undefined default imports)","After SSR version upgrades, diff server.ts against the new template"],"tags":["angular","ssr","configuration"],"backgroundTag":"missing-bootstrap-option","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}