{"record":{"id":"55496bb630a8f85e","repo":"angular/angular-cli","slug":"error-s-occurred-while-extracting-routes-n-erro","errorCode":null,"errorMessage":"Error(s) occurred while extracting routes:\\n${errors.map((error) => `- ${error}`).join('\\n')}","messagePattern":"Error\\(s\\) occurred while extracting routes:\\\\n(.+?)`\\)\\.join\\('\\\\n'\\)\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular/ssr/src/routes/router.ts","lineNumber":60,"sourceCode":"   * @param manifest - An instance of `AngularAppManifest` that contains the route information.\n   * @param url - The URL for server-side rendering. The URL is needed to configure `ServerPlatformLocation`.\n   * This is necessary to ensure that API requests for relative paths succeed, which is crucial for correct route extraction.\n   * [Reference](https://github.com/angular/angular/blob/d608b857c689d17a7ffa33bbb510301014d24a17/packages/platform-server/src/location.ts#L51)\n   * @returns A promise resolving to a `ServerRouter` instance.\n   */\n  static from(manifest: AngularAppManifest, url: URL): Promise<ServerRouter> {\n    if (manifest.routes) {\n      const routeTree = RouteTree.fromObject(manifest.routes);\n\n      return Promise.resolve(new ServerRouter(routeTree));\n    }\n\n    // Create and store a new promise for the build process.\n    // This prevents concurrent builds by re-using the same promise.\n    ServerRouter.#extractionPromise ??= extractRoutesAndCreateRouteTree({ url, manifest })\n      .then(({ routeTree, errors }) => {\n        if (errors.length > 0) {\n          throw new Error(\n            'Error(s) occurred while extracting routes:\\n' +\n              errors.map((error) => `- ${error}`).join('\\n'),\n          );\n        }\n\n        return new ServerRouter(routeTree);\n      })\n      .finally(() => {\n        ServerRouter.#extractionPromise = undefined;\n      });\n\n    return ServerRouter.#extractionPromise;\n  }\n\n  /**\n   * Matches a request URL against the route tree to retrieve route metadata.\n   *\n   * This method strips 'index.html' from the URL if it is present and then attempts","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/ssr/src/routes/router.ts#L42-L78","documentation":"`ServerRouter.from()` aggregates all errors encountered while extracting routes (walking the Angular route config and building the route tree). If any extraction errors were collected, it throws one combined `Error` listing each error as a bullet line, instead of returning a partially built router. The individual underlying errors are embedded in the message after the `- ` bullets.","triggerScenarios":"Any route-extraction failure during `ServerRouter.from({ url, manifest })` — e.g. errors emitted by route handling (like invalid prerender params or non-prerender metadata dispatch) — when `appendPreloadToMetadata` or `toObject` triggers extraction at build/request time.","commonSituations":"SSG builds where one or more routes failed extraction (read the `- ...` bullet lines for the real causes); corrupt or inconsistent server route manifests; concurrent builds racing on the shared `#extractionPromise` is prevented, but a failed first build rejects all waiters.","solutions":["Read each `- ...` bullet in the thrown message — they name the per-route root causes — and fix those first.","Run the route extraction for a single URL (or `ng build` verbosely) to isolate which route config entry fails.","Validate `app.routes.server.ts` for invalid render modes, missing `getPrerenderParams`, or bad lazy loaders.","Clean rebuild (`rm -rf .angular dist && ng build`) to rule out stale cache; report a bug if bullets are empty."],"exampleFix":"// reading the error\n// Error(s) occurred while extracting routes:\n//   - 'getPrerenderParams' ... returned a non-string value for parameter 'id'\n// fix the listed route, e.g.\n{ path: 'products/:id', renderMode: RenderMode.Prerender, getPrerenderParams: async () => [{ id: '1' }] }\n","handlingStrategy":"try-catch","validationCode":"// pre-validate routes before extraction\nfor (const r of serverRoutes) {\n  if (r.renderMode === RenderMode.Prerender && ':' in r.path && !('getPrerenderParams' in r)) {\n    throw new Error(`Route ${r.path} needs getPrerenderParams`);\n  }\n}","typeGuard":"function isServerRouter(v: unknown): v is ServerRouter {\n  return v instanceof ServerRouter;\n}","tryCatchPattern":"try {\n  const router = await ServerRouter.from({ url, manifest });\n} catch (e) {\n  if (String(e?.message).startsWith('Error(s) occurred while extracting routes:')) {\n    const causes = String(e.message).split('\\n').filter(l => l.trim().startsWith('- '));\n    console.error('Route extraction failures:', causes);\n  } else throw e;\n}","preventionTips":["Always parse the `- ` bullet lines in this aggregate error — they contain the real per-route causes.","Validate server route configs (render modes, params callbacks) before builds.","Run route extraction/prerender in CI to catch extraction failures early.","Clean `.angular` cache on unexplained extraction errors after upgrades."],"tags":["angular","ssr","route-extraction","build","aggregate-error"],"backgroundTag":"route-extraction-failed","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}