anomalyco/sst · error · VisibleError

TanStack Start build output at "${path.resolve(wranglerPath)

Error message

TanStack Start build output at "${path.resolve(wranglerPath)}" is missing the Worker entry in `main`.

What it means

When SST finds `dist/server/wrangler.json` in a TanStack Start build, it reads the Worker entrypoint from its `main` field. If `main` is missing or empty, SST cannot locate the worker script and throws this VisibleError.

Source

Thrown at platform/src/components/cloudflare/tan-stack-start.ts:308

        ].join("\n"),
      );

      async function resolveDistPlan() {
        const wranglerPath = path.join(
          outputPath,
          "dist",
          "server",
          "wrangler.json",
        );
        if (await existsAsync(wranglerPath)) {
          const wrangler = JSON.parse(await fs.readFile(wranglerPath, "utf-8")) as {
            main?: string;
            assets?: {
              directory?: string;
            };
          };
          if (!wrangler.main) {
            throw new VisibleError(
              `TanStack Start build output at "${path.resolve(wranglerPath)}" is missing the Worker entry in \`main\`.`,
            );
          }

          const serverPath = path.resolve(outputPath, "dist", "server", wrangler.main);
          const assetsPath = path.resolve(
            outputPath,
            "dist",
            "server",
            wrangler.assets?.directory ?? "../client",
          );

          if (!(await existsAsync(serverPath))) {
            throw new VisibleError(
              `TanStack Start server bundle not found at:\n  "${serverPath}".`,
            );
          }
          if (!(await existsAsync(assetsPath))) {

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Clean the `dist/` directory and rebuild with the official Cloudflare adapter so `main` is generated
  2. Do not commit or hand-edit `dist/server/wrangler.json`; configure the adapter instead of editing build output
  3. Update `@tanstack/cloudflare-vite-plugin` to a current version that writes the `main` field

Example fix

// before (dist/server/wrangler.json, hand-edited)
{ "name": "app", "assets": { "directory": "../client" } }
// after: rm -rf dist && rebuild via adapter
{ "name": "app", "main": "index.js", "assets": { "directory": "../client" } }
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync, existsSync } from 'fs';
const w = JSON.parse(readFileSync('apps/web/dist/server/wrangler.json', 'utf8'));
if (!w.main) throw new Error('dist/server/wrangler.json missing `main`; rebuild with the Cloudflare adapter');
if (!existsSync(`apps/web/dist/server/${w.main}`)) throw new Error(`main file missing: ${w.main}`);

Type guard

function wranglerHasMain(w: unknown): w is { main: string } {
  return typeof w === 'object' && w !== null && 'main' in w && typeof (w as { main: unknown }).main === 'string' && (w as { main: string }).main.length > 0;
}

Try / catch

try {
  await deploy();
} catch (e) {
  if (/missing the Worker entry in `main`/.test(e.message)) console.error('Do not hand-edit dist/server/wrangler.json; rebuild with the adapter');
}

Prevention

When it happens

Trigger: A TanStack Start build emits `dist/server/wrangler.json` without a `main` property: hand-edited or stale wrangler.json, adapter misconfiguration, or an older/newer adapter writing an incompatible config shape.

Common situations: Manually committing a wrangler.json into dist/server that overrides the generated one; version mismatch between the TanStack Cloudflare adapter and SST's expectations; interrupted builds leaving a partial wrangler.json.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/e0969646747b45a9. Report an issue: GitHub.