angular/angular-cli · error · Error

Error(s) occurred while extracting routes:\n${errors.map((er

Error message

Error(s) occurred while extracting routes:\n${errors.map((error) => `- ${error}`).join('\n')}

What it means

`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.

Source

Thrown at packages/angular/ssr/src/routes/router.ts:60

   * @param manifest - An instance of `AngularAppManifest` that contains the route information.
   * @param url - The URL for server-side rendering. The URL is needed to configure `ServerPlatformLocation`.
   * This is necessary to ensure that API requests for relative paths succeed, which is crucial for correct route extraction.
   * [Reference](https://github.com/angular/angular/blob/d608b857c689d17a7ffa33bbb510301014d24a17/packages/platform-server/src/location.ts#L51)
   * @returns A promise resolving to a `ServerRouter` instance.
   */
  static from(manifest: AngularAppManifest, url: URL): Promise<ServerRouter> {
    if (manifest.routes) {
      const routeTree = RouteTree.fromObject(manifest.routes);

      return Promise.resolve(new ServerRouter(routeTree));
    }

    // Create and store a new promise for the build process.
    // This prevents concurrent builds by re-using the same promise.
    ServerRouter.#extractionPromise ??= extractRoutesAndCreateRouteTree({ url, manifest })
      .then(({ routeTree, errors }) => {
        if (errors.length > 0) {
          throw new Error(
            'Error(s) occurred while extracting routes:\n' +
              errors.map((error) => `- ${error}`).join('\n'),
          );
        }

        return new ServerRouter(routeTree);
      })
      .finally(() => {
        ServerRouter.#extractionPromise = undefined;
      });

    return ServerRouter.#extractionPromise;
  }

  /**
   * Matches a request URL against the route tree to retrieve route metadata.
   *
   * This method strips 'index.html' from the URL if it is present and then attempts

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Read each `- ...` bullet in the thrown message — they name the per-route root causes — and fix those first.
  2. Run the route extraction for a single URL (or `ng build` verbosely) to isolate which route config entry fails.
  3. Validate `app.routes.server.ts` for invalid render modes, missing `getPrerenderParams`, or bad lazy loaders.
  4. Clean rebuild (`rm -rf .angular dist && ng build`) to rule out stale cache; report a bug if bullets are empty.

Example fix

// reading the error
// Error(s) occurred while extracting routes:
//   - 'getPrerenderParams' ... returned a non-string value for parameter 'id'
// fix the listed route, e.g.
{ path: 'products/:id', renderMode: RenderMode.Prerender, getPrerenderParams: async () => [{ id: '1' }] }
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate routes before extraction
for (const r of serverRoutes) {
  if (r.renderMode === RenderMode.Prerender && ':' in r.path && !('getPrerenderParams' in r)) {
    throw new Error(`Route ${r.path} needs getPrerenderParams`);
  }
}

Type guard

function isServerRouter(v: unknown): v is ServerRouter {
  return v instanceof ServerRouter;
}

Try / catch

try {
  const router = await ServerRouter.from({ url, manifest });
} catch (e) {
  if (String(e?.message).startsWith('Error(s) occurred while extracting routes:')) {
    const causes = String(e.message).split('\n').filter(l => l.trim().startsWith('- '));
    console.error('Route extraction failures:', causes);
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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