anomalyco/sst · error · VisibleError

No "build" script found within package.json in "${sitePath}"

Error message

No "build" script found within package.json in "${sitePath}".

What it means

After loading package.json, resolveBuildCommand checks for a scripts.build entry and throws this error when the package.json exists but has no build script (or no scripts at all). SST builds SSR sites with `npm run build` (or the package manager equivalent) by default, so a build script is required.

Source

Thrown at platform/src/components/base/base-ssr-site.ts:51

  ]).apply(
    ([sitePath, userCommand, links, environment, extraBuildEnvironment]) => {
      const cmd = resolveBuildCommand();
      const result = runBuild();
      return result.id.apply(() => sitePath);

      function resolveBuildCommand() {
        if (userCommand) return userCommand;

        // Ensure that the site has a build script defined
        if (!userCommand) {
          if (!fs.existsSync(path.join(sitePath, "package.json"))) {
            throw new VisibleError(`No package.json found at "${sitePath}".`);
          }
          const packageJson = JSON.parse(
            fs.readFileSync(path.join(sitePath, "package.json")).toString(),
          );
          if (!packageJson.scripts || !packageJson.scripts.build) {
            throw new VisibleError(
              `No "build" script found within package.json in "${sitePath}".`,
            );
          }
        }

        if (
          fs.existsSync(path.join(sitePath, "yarn.lock")) ||
          fs.existsSync(path.join($cli.paths.root, "yarn.lock"))
        )
          return "yarn run build";
        if (
          fs.existsSync(path.join(sitePath, "pnpm-lock.yaml")) ||
          fs.existsSync(path.join($cli.paths.root, "pnpm-lock.yaml"))
        )
          return "pnpm run build";
        if (
          fs.existsSync(path.join(sitePath, "bun.lockb")) ||
          fs.existsSync(path.join($cli.paths.root, "bun.lockb")) ||

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Add a "build" script to the site's package.json.
  2. Or pass an explicit `build` command in the site component args to bypass the default script lookup.
  3. Verify you're pointing at the right package (in monorepos) that actually has the build script.

Example fix

// before: package.json
{ "name": "web", "scripts": { "dev": "vite" } }
// after
{ "name": "web", "scripts": { "dev": "vite", "build": "vite build" } }
Defensive patterns

Strategy: validation

Validate before calling

const pkg = JSON.parse(fs.readFileSync(`${sitePath}/package.json`, "utf8"));
if (!pkg.scripts?.build)
  throw new Error(`Add a "build" script to ${sitePath}/package.json or pass build.command in the site args.`);

Prevention

When it happens

Trigger: Site's package.json lacks `scripts.build` — e.g. only has dev/start scripts, or an empty scripts object — while deploying an SSR site without a custom `build` command in args.

Common situations: Frameworks or boilerplates without a standard build script; monorepo packages whose build lives in a parent workspace; freshly scaffolded projects that never defined build.

Related errors


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