{"record":{"id":"801d9dff4c09e8c9","repo":"anomalyco/sst","slug":"ssr-server-bundle-not-found-in-the-build-output-at","errorCode":null,"errorMessage":"SSR server bundle not found in the build output at:\n  \"${path.resolve(distPath)}\".\n\nExpected either Astro v5 output in `dist/_worker.js/index.js` or Astro v6+ output in `dist/server/wrangler.json`.\nIf your Astro project is entirely pre-rendered, use the `sst.cloudflare.StaticSite` component instead of `sst.cloudflare.Astro`.","messagePattern":"SSR server bundle not found in the build output at:\n  \"(.+?)\"\\.\n\nExpected either Astro v5 output in `dist/_worker\\.js/index\\.js` or Astro v6\\+ output in `dist/server/wrangler\\.json`\\.\nIf your Astro project is entirely pre-rendered, use the `sst\\.cloudflare\\.StaticSite` component instead of `sst\\.cloudflare\\.Astro`\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/cloudflare/astro.ts","lineNumber":329,"sourceCode":"        const wrangler = JSON.parse(\n          await fs.readFile(wranglerPath, \"utf-8\"),\n        ) as WranglerConfig;\n        const main = wrangler.main ?? \"entry.mjs\";\n        const serverEntry = path.resolve(serverPath, main);\n        const assetsDirectory = wrangler.assets?.directory;\n        const assetsPath = assetsDirectory\n          ? path.resolve(serverPath, assetsDirectory)\n          : path.join(distPath, \"client\");\n\n        if (await existsAsync(serverEntry)) {\n          return {\n            server: toRelativePath(serverEntry),\n            assets: toRelativePath(assetsPath),\n          };\n        }\n      }\n\n      throw new VisibleError(\n        `SSR server bundle not found in the build output at:\\n` +\n          `  \"${path.resolve(distPath)}\".\\n\\n` +\n          `Expected either Astro v5 output in \\`dist/_worker.js/index.js\\` or Astro v6+ output in \\`dist/server/wrangler.json\\`.\\n` +\n          `If your Astro project is entirely pre-rendered, use the \\`sst.cloudflare.StaticSite\\` component instead of \\`sst.cloudflare.Astro\\`.`,\n      );\n\n      function toRelativePath(filePath: string) {\n        const relative = path.relative(outputPath, filePath);\n        return relative.startsWith(\".\") ? relative : `./${relative}`;\n      }\n    });\n  }\n\n  /**\n   * The URL of the Astro site.\n   *\n   * If the `domain` is set, this is the URL with the custom domain.\n   * Otherwise, it's the auto-generated Worker URL.","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/cloudflare/astro.ts#L311-L347","documentation":"sst.cloudflare.Astro expects the Astro build to produce an SSR server bundle, but after running `astro build` no recognized server output was found at the configured dist path. SST supports Astro v5 layout (`dist/_worker.js/index.js`) and Astro v6+ layout (`dist/server/wrangler.json`). If the site is fully static (no SSR/on-demand routes), Astro produces no server bundle and the StaticSite component must be used instead.","triggerScenarios":"Running `sst deploy` (buildPlan in platform/src/components/cloudflare/astro.ts) after an Astro build where neither `dist/_worker.js/index.js` nor `dist/server/wrangler.json` exists — typically because `output: 'static'` is set in astro.config, or because the build never ran / ran into a different dist directory.","commonSituations":"Astro project configured as fully static but wrapped in sst.cloudflare.Astro; Astro build failed silently or was skipped; `dist` directory stale or cleaned; Astro version mismatch producing an unexpected output layout; custom `outDir` not matching what SST inspects.","solutions":["If the site is entirely pre-rendered, replace `sst.cloudflare.Astro` with `sst.cloudflare.StaticSite` in your sst.config.ts.","If you need SSR, set `output: 'server'` (or use on-demand rendering) in astro.config.mjs and rebuild.","Run the Astro build and confirm the expected bundle exists (`dist/_worker.js/index.js` for v5, `dist/server/wrangler.json` for v6+).","Ensure the component's `path`/build output settings point at the directory Astro actually writes to."],"exampleFix":"// before (sst.config.ts)\nconst site = new sst.cloudflare.Astro(ctx, \"Site\", {});\n// after (for a fully static site)\nconst site = new sst.cloudflare.StaticSite(ctx, \"Site\", {\n  path: \"my-astro-app\",\n  build: { output: \"dist\" },\n});","handlingStrategy":"validation","validationCode":"import fs from \"fs\";\nimport path from \"path\";\nconst dist = \"my-astro-app/dist\";\nconst isV5 = fs.existsSync(path.join(dist, \"_worker.js/index.js\"));\nconst isV6 = fs.existsSync(path.join(dist, \"server/wrangler.json\"));\nif (!isV5 && !isV6) console.warn(\"No SSR bundle: use sst.cloudflare.StaticSite or set output: 'server'\");","typeGuard":"const hasSsrOutput = (dist: string) =>\n  fs.existsSync(path.join(dist, \"_worker.js/index.js\")) ||\n  fs.existsSync(path.join(dist, \"server/wrangler.json\"));","tryCatchPattern":"try {\n  new sst.cloudflare.Astro(app, \"Site\", {});\n} catch (e) {\n  if (String(e).includes(\"SSR server bundle not found\")) {\n    // fall back to StaticSite or fix astro output config\n  } else throw e;\n}","preventionTips":["Set `output: 'server'` in astro.config.mjs for SSR apps.","Use sst.cloudflare.StaticSite for fully pre-rendered Astro sites.","Run `astro build` before `sst deploy` and check the dist layout.","Pin Astro version and confirm its output layout matches SST's expectations."],"tags":["cloudflare","astro","ssr","build-output","misconfiguration"],"backgroundTag":"ssr-build-output-not-found","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}