{"record":{"id":"7382ddb47e80b5b5","repo":"angular/angular-cli","slug":"handlessgroute-was-called-for-a-route-which-rend","errorCode":null,"errorMessage":"'handleSSGRoute' was called for a route which rendering mode is not prerender.","messagePattern":"'handleSSGRoute' was called for a route which rendering mode is not prerender\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular/ssr/src/routes/ng-routes.ts","lineNumber":410,"sourceCode":" *\n * @param serverConfigRouteTree - The tree representing the server's routing setup.\n * @param redirectTo - Optional path to redirect to, if specified.\n * @param metadata - The metadata associated with the route tree node.\n * @param parentInjector - The dependency injection container for the parent route.\n * @param invokeGetPrerenderParams - A flag indicating whether to invoke the `getPrerenderParams` function.\n * @param includePrerenderFallbackRoutes - A flag indicating whether to include fallback routes in the result.\n * @returns An async iterable iterator that yields route tree node metadata for each SSG path or errors.\n */\nasync function* handleSSGRoute(\n  serverConfigRouteTree: RouteTree<ServerConfigRouteTreeAdditionalMetadata> | undefined,\n  redirectTo: string | undefined,\n  metadata: ServerConfigRouteTreeNodeMetadata,\n  parentInjector: Injector,\n  invokeGetPrerenderParams: boolean,\n  includePrerenderFallbackRoutes: boolean,\n): AsyncIterableIterator<RouteTreeNodeMetadata | { error: string }> {\n  if (metadata.renderMode !== RenderMode.Prerender) {\n    throw new Error(\n      `'handleSSGRoute' was called for a route which rendering mode is not prerender.`,\n    );\n  }\n\n  const { route: currentRoutePath, fallback, ...meta } = metadata;\n  const getPrerenderParams = 'getPrerenderParams' in meta ? meta.getPrerenderParams : undefined;\n\n  if ('getPrerenderParams' in meta) {\n    delete meta['getPrerenderParams'];\n  }\n\n  if (redirectTo !== undefined) {\n    meta.redirectTo = resolveRedirectTo(currentRoutePath, redirectTo);\n  }\n\n  const isCatchAllRoute = CATCH_ALL_REGEXP.test(currentRoutePath);\n  if (\n    (isCatchAllRoute && !getPrerenderParams) ||","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/ssr/src/routes/ng-routes.ts#L392-L428","documentation":"This error is thrown by the Angular SSR route-tree builder when `handleSSGRoute` is invoked for a route whose `renderMode` is not `RenderMode.Prerender`. It is an internal invariant check: only prerender-mode route metadata should ever reach the SSG handling path. Hitting it means the route tree construction logic dispatched a non-prerender route (e.g. Server or Client render mode) into the static-generation handler.","triggerScenarios":"A route's ServerRoute metadata has renderMode set to Server/Client but is passed to `handleSSGRoute` during route extraction; typically caused by mismatched route configuration or an internal dispatch bug in `handleRoute`.","commonSituations":"Mixing `RenderMode.Server` or `RenderMode.Client` routes with prerender expectations in `app.routes.server.ts`; upgrading @angular/ssr where route metadata shapes changed; custom route-tree tooling calling internal APIs directly.","solutions":["Inspect `app.routes.server.ts` and ensure every route fed into SSG/prerender handling declares `renderMode: RenderMode.Prerender`.","Set the intended mode explicitly, e.g. `{ '/**': { renderMode: RenderMode.Server } }` for dynamic routes instead of relying on defaults.","Remove any custom code that calls `handleSSGRoute` (or route-tree internals) directly with non-prerender metadata.","Update @angular/ssr and @angular/core to matching latest patch versions and rebuild; if reproducible on clean config, file a bug with a minimal repo."],"exampleFix":"// before (server routes)\nconst serverRoutes: ServerRoute[] = [\n  { path: 'products/:id', renderMode: RenderMode.Server },\n];\n// after\nconst serverRoutes: ServerRoute[] = [\n  { path: 'products/:id', renderMode: RenderMode.Prerender, getPrerenderParams: async ({ params }) => [/* ids */] },\n];","handlingStrategy":"validation","validationCode":"import { RenderMode } from '@angular/ssr';\nconst isPrerender = (m: { renderMode?: RenderMode }) => m.renderMode === RenderMode.Prerender;\nif (!serverRoutes.every(r => !needsSsg(r.path) || isPrerender(r))) {\n  throw new Error('SSG routes must declare renderMode: RenderMode.Prerender');\n}","typeGuard":"function isPrerenderMetadata(m: ServerConfigRouteTreeNodeMetadata): boolean {\n  return m.renderMode === RenderMode.Prerender;\n}","tryCatchPattern":"try {\n  for await (const meta of handleSSGRoute(route, metadata, injector, true, true)) { /* ... */ }\n} catch (e) {\n  if (String(e?.message).includes(\"'handleSSGRoute' was called\")) {\n    console.error('Route is not prerender-mode:', metadata.route, metadata.renderMode);\n  } else throw e;\n}","preventionTips":["Explicitly declare `renderMode` on every entry in `app.routes.server.ts`; never rely on defaults.","Keep @angular/core and @angular/ssr versions exactly in sync.","Do not call internal route-tree APIs (`handleSSGRoute`) from application code.","Run a prerender build in CI to surface mode mismatches early."],"tags":["angular","ssr","prerender","route-configuration"],"backgroundTag":"prerender-render-mode-mismatch","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}