Netlify says "Build script returned non-zero exit code: 2" on my Bolt app. What now?

Checked on

In plain words: Netlify couldn't build your site. This line only tells you the build failed; it's not the cause. Netlify's own docs say to scroll up in the build log to the first real error before it. For Bolt (Vite + React + TypeScript) apps, that's usually one of five things: a TypeScript error the preview ignored, an import whose capitalisation doesn't match the file name, a different Node version, a missing build-time environment variable, or a warning treated as an error because Netlify sets CI=true.

Symptoms

  • The deploy log ends with Build script returned non-zero exit code: 2 and Failing build: Failed to build site (Netlify: Error reference).
  • The app runs fine in Bolt's preview.
  • Your latest changes never appear on the live site, or there's no live site at all if it never deployed.
  • Publishing from Bolt to Netlify fails, or a GitHub-connected Netlify site fails after a push.

Why it happens

Netlify: "If you check your build log before the non-zero exit code, you can usually find more details about the reason for the failure." Its steps: go to Deploys, choose the failed deploy, open the build log, and scroll up to the failure (Netlify: Error reference).

The usual causes for Bolt apps:

  1. TypeScript errors. Vite's dev server (what the preview runs) doesn't type-check. Vite's docs say it "only performs transpilation on .ts files and does NOT perform type checking" (Vite: Features). Many Vite TypeScript templates run tsc as part of npm run build, so type errors that never showed in the preview fail the build. Check your package.json build script.
  2. Case-sensitive file names. Netlify's build file system is case-sensitive, and the error "may not clearly indicate this" (Netlify: Build troubleshooting tips). import Header from './header' fails if the file is Header.tsx. The log usually says Could not resolve or Cannot find module.
  3. A different Node.js version. Netlify calls version mismatches "the leading cause of build failure" (Build troubleshooting tips).
  4. Warnings treated as errors. Netlify sets CI=true, and some tools fail on warnings when they see it. Netlify suggests CI='' npm run build as the build command, and warns that CI=false "may not work as expected" (Build troubleshooting tips).
  5. Missing environment variables or a wrong build setup. For Vite apps, Netlify's Bolt guide gives build command npm run build and publish directory dist (Netlify: Deploy your Bolt app).

Step-by-step fix

1. Read the first real error

Open the failed deploy's log and scroll up from non-zero exit code to the first line with error, Error: or failed. Copy from there to the end. Netlify's error reference also mentions a Why did it fail? option on failed deploys that gives a diagnosis without using credits (Netlify: Error reference).

2. Reproduce the build in Bolt

In Bolt's terminal, run npm run build rather than the dev server. You'll usually see the same error. Bolt's docs mention running commands in Code view (Bolt: issues).

3. Fix by error type

Log showsFix
error TS2322, TS2339, any TSxxxxFix the type error in that file and line (or have your AI tool fix exactly that error). Don't delete tsc from the build to hide it.
Could not resolve "./header" / Cannot find moduleMake the import match the file name exactly, capitals included. If the file is missing, restore it.
Unsupported engine, syntax errors in node_modules, or node: not found-style errorsPin Node: set NODE_VERSION (for example 20) in Netlify environment variables, or add a .nvmrc/.node-version file. These override the Node setting in Netlify's UI (Netlify: Manage dependencies).
Treating warnings as errors because process.env.CI = trueFix the warnings, or set the build command to CI='' npm run build.
Could not resolve dependency / Conflicting peer dependencyNetlify suggests setting NPM_FLAGS to --legacy-peer-deps (or --force) for this case (Build troubleshooting tips).
An env var is undefined during the buildAdd it under Netlify's environment variables, then redeploy.

4. Check build settings

For a Vite app: build command npm run build, publish directory dist (Netlify: Bolt guide).

5. Redeploy

Push the fix or republish from Bolt. If you duplicated or forked the Bolt project, Bolt's docs say you'll need to reconnect it to Netlify, which creates a new Netlify site (Bolt: Publishing issues).

Fix prompt for your AI builder

Paste this into Lovable, Bolt, Cursor, Replit, v0 or whichever tool you build with:

Fix prompt
My Netlify deploy fails with "Build script returned non-zero exit code: 2". Here is the build log from the first error to the end:
<PASTE LOG>
Fix only what this log reports:
1. Run `npm run build` (not the dev server) and fix every error it shows, including TypeScript errors. Don't remove type checking from the build script to hide them.
2. Make every import path match the real file name exactly, including capital letters.
3. If the Node version is the problem, add an .nvmrc with the Node major version this project needs.
4. List any environment variables the build needs so I can add them in Netlify.
Confirm `npm run build` succeeds before you finish, and list the files you changed.

How to confirm it's fixed

  1. npm run build succeeds in Bolt's terminal.
  2. The next Netlify deploy shows Published.
  3. Open the live URL in a private window and click through a few pages. If it builds but shows a blank page, see Bolt.new app blank white page on Netlify?

How to find out sooner next time

When a build fails, your fix simply never ships, and nothing on the live site tells you. Heedza checks your live landing, signup, login and checkout pages on a schedule and sends you a screenshot and a fix prompt if one stops loading or loses its form. It doesn't read your build logs or watch deploys. The free scan also checks whether files like /.env and /.git/config are publicly readable on your site.

Let Heedza check this for you. Heedza’s online and page check keeps checking that your live home page opens with real content, and that your sign-up, log-in and payment pages still open and show their forms and Pay buttons. It never logs in or fills in forms, so it can’t see errors that only show after that.

Made with Bolt, Lovable, Replit, Cursor or v0? Free for 1 site: start free or see prices.

More questions

Why does it work in Bolt's preview?

The preview runs Vite's dev server, which doesn't type-check, and it uses your preview environment. The production build runs the full build script (often including tsc) on Netlify's case-sensitive file system with Netlify's Node version and environment variables.

What's the difference between exit code 1 and 2?

For fixing it, nothing much: both mean the build command failed. Netlify's docs treat "non-zero exit code" as one case. Read the error above it.

Can I just disable TypeScript checks?

You can, but the errors usually point at real bugs (a property that doesn't exist, a value that can be undefined). Fixing them is usually quicker than debugging the live site later.

Where this comes from