Composer applies the edit, there are no red squiggles in the files it touched, you run pnpm build, and it blows up: missing imports, type drift, an out-of-date Prisma client, an ESM/CJS mismatch. The reason is mechanical, not mysterious. Cursor’s Apply only validates the local file it edited; it does not run a full-graph typecheck, it does not run your codegen step, and it has no idea what your CI container looks like. So you get locally green, globally red.
Fastest fix (do this first): make the agent build the project itself before it reports “done.” In Cursor, open Settings → Agent → Auto-run (this is the renamed “Yolo mode” in current Cursor, as of June 2026), and add a natural-language allow-list such as “may run pnpm typecheck, pnpm build, pnpm test, and eslint.” Then give Composer a rule: “After any code change, run pnpm build; if it fails, fix it and run again; only stop when it is green.” Most of the failures below disappear because the agent now sees the same error you do and iterates on it.
The rest of this page is the diagnostic when one error still slips through.
Which bucket are you in?
Match the first line of your build error against this table, then jump to the matching fix below.
| Build error contains | Likely cause | Go to |
|---|---|---|
Expected N arguments, but got M | Signature changed, not all call sites updated | Cause 1 / Step 2 |
Cannot find module / Module not found | New file, wrong import path or alias | Cause 2 / Step 3 |
Path points at .prisma/, src/generated/, __generated__/ | Codegen never re-ran | Cause 3 / Step 4 |
ERR_REQUIRE_ESM / Cannot use import statement outside a module / X is not a function | ESM/CJS mismatch | Cause 4 / Step 5 |
| An env var name or a fixture file path; passes locally, fails in CI | Code reads env/files CI lacks | Cause 5 / Step 6 |
Type error you cannot reproduce with tsc --noEmit locally | Build uses a stricter tsconfig | Cause 6 / Step 6 |
Common causes
1. Signature changed; not all call sites updated
Cursor turns foo(a, b) into foo(a, b, c) but only updates the 3 call sites it had open. The other 7 in the repo break with Expected 3 arguments, but got 2.
How to judge: run pnpm typecheck and pipe it through grep "Expected" — the errors cluster around one function or type.
2. New file missing import or wrong import path
Composer creates src/utils/parseInvoice.ts but callers import from "./utils/parse-invoice" (kebab-case) or from "@/utils/parseInvoice" (depends on a path alias that may not be configured). The dev server is tolerant; the build is strict.
How to judge: the build error mentions Cannot find module or Module not found.
3. Codegen didn’t run
After a Prisma / GraphQL / protobuf / OpenAPI schema change, the generated client or types were never regenerated. The new field referenced in code does not exist yet in the generated output.
How to judge: the error points at node_modules/.prisma/, src/generated/, __generated__/, or a similar generated path.
4. ESM / CJS mismatch
Composer wrote import { foo } from "esm-only-package" in a CommonJS project, or used require() in a pure ESM project. Dev runners (ts-node / tsx) tolerate the mix; bundlers (esbuild / Vite / Rollup) break.
How to judge: the error says ERR_REQUIRE_ESM, Cannot use import statement outside a module, or X is not a function.
5. References env / files that don’t exist in CI
New code reads process.env.NEW_TOKEN or a local fixture file. It works on your machine; the CI container has neither, so the build throws undefined or ENOENT.
How to judge: the build error names an env variable or a file path; local builds fine, CI breaks.
6. Multiple tsconfigs (dev vs build)
tsconfig.json is lax (noEmit, skipLibCheck); tsconfig.build.json is strict (strict, noUnusedLocals). Cursor and your editor check against the loose one; the build uses the strict one.
How to judge: run ls tsconfig*.json — if there are multiple files, compare their strict flags.
Before you start
- Identify whether the build fails locally, in CI, or only in a production deploy. A one-spot failure points at an env or config diff (causes 5 and 6).
- Commit before reproducing so you can tell exactly which change broke what, and so you can cleanly roll back.
- Note the Cursor version and the active model (Composer 2.5, Sonnet 4.6, GPT-5.5, etc.). Import-path style varies between models — some prefer relative paths, some prefer a path alias.
Info to collect
- The full build error log — keep the first line and the last line; the middle is usually cascading noise.
- The last Composer turn’s prompt plus its diff stat.
tsconfig.json/tsconfig.build.json, and thebuildscript inpackage.json.- Whether a codegen step exists and when it last ran successfully.
- Local Node / pnpm versions vs the versions CI uses.
Shortest fix path
Work in “full-graph scan, then patch by error class” order.
Step 1: Full typecheck + build
pnpm typecheck # or tsc --noEmit
pnpm build
Read the first error, not the last. AI-introduced errors cascade, and the first one sits closest to the root cause.
Step 2: Signature changes — have Composer find the call sites
I changed the signature of `foo` from (a, b) to (a, b, c).
List EVERY call site in the repo and update each one.
After updating, run `pnpm typecheck` and paste the result.
Make the agent run typecheck itself instead of trusting its own scan.
Step 3: Missing import — fix the path
Build fails with "Cannot find module './utils/parse-invoice'".
The file is actually at src/utils/parseInvoice.ts (camelCase).
Update all import paths to match. Verify with tsc --noEmit.
Step 4: Stale codegen — regenerate
pnpm prisma generate
pnpm codegen # GraphQL
pnpm proto # protobuf
Make codegen a standing rule. The modern way to do this in Cursor is a project rule file, not the legacy .cursorrules file (which still works but is being phased out — see the FAQ). Create .cursor/rules/codegen.mdc with frontmatter alwaysApply: true and this body:
After any change to a *.prisma, *.graphql, or *.proto file, run the
matching codegen command (e.g. `pnpm prisma generate`) before declaring
the task done.
Step 5: ESM/CJS — match the project type
Check the "type" field in package.json. "type": "module" means use import throughout; a missing field or "type": "commonjs" means use require. Have Composer harmonize the file with the rest of the project, and remember that ESM needs explicit .js extensions in relative imports (from "./foo.js", not from "./foo").
Step 6: CI-only failures — env + tsconfig diff
diff tsconfig.json tsconfig.build.json
grep -A 3 "env" .github/workflows/*.yml
Hand the strict config to Composer:
We use tsconfig.build.json (strict mode) for production. Re-check your
changes under that config and fix any new errors. Run:
tsc -p tsconfig.build.json --noEmit
For missing env vars, confirm the variable is declared in your CI secrets and in .env.example, not only in your local .env.
How to confirm it’s fixed
- Local
pnpm typecheck && pnpm buildboth pass. - After you push, CI is fully green — the build and the whole test suite, not just unit tests.
- On a clean checkout,
pnpm install && pnpm buildworks. This catches env drift and a lockfile that quietly changed. - Going forward, with Auto-run on, Composer’s last message should literally say it ran the build and it passed.
If it still fails
- Reduce to the smallest broken thing: one import, or one type error.
- Roll back the Composer commit, confirm the build recovers, then reapply the changes hunk by hunk to find the offending one.
- Search forum.cursor.com for the exact error string; attach your
tsconfig,package.json, and the log. - Export logs via Help → Report Issue (you can attach diagnostic logs), or grab the agent output and post it to the Bug Reports category.
Prevention
- CI policy: every PR runs full typecheck + build + the whole test suite, not just unit tests.
- Turn on Settings → Agent → Auto-run with an allow-list for
typecheck,build,lint, andtestso Composer verifies itself. Keep destructive commands (rm -rf,git push --force) off the allow-list. - Add a project rule:
.cursor/rules/verify.mdcwithalwaysApply: truesaying “After any code change, runpnpm buildand report errors before finishing.” (AGENTS.mdin the repo root works too if you prefer a single plain-markdown file.) - Pre-commit hook: at minimum
tsc --noEmiton staged files plus their importers. - For schema-driven projects (Prisma / GraphQL / Protobuf), make “schema change then codegen” a non-negotiable rule.
- End Composer tasks on “I ran the build and it succeeded,” not “I’m done.”
FAQ
Why does Cursor say the edit is clean when the build clearly isn’t?
Apply only typechecks the single file it edited, in the editor’s loose context. It does not run a project-wide tsc, your codegen step, or your bundler, and it never sees your CI config. The fix is to make the agent actually run the build (Auto-run), so its idea of “done” matches yours.
Should I use .cursorrules or .cursor/rules/*.mdc?
Prefer .cursor/rules/*.mdc. As of June 2026 the single-file .cursorrules still loads but is treated as legacy and is being phased out. The .cursor/rules directory holds versioned .mdc files with four apply modes — Always, Apply Intelligently, Apply to Specific Files (globs), and Manual (@rule-name). Use alwaysApply: true for a build-verification rule. A root AGENTS.md is a simpler plain-markdown alternative Cursor also reads.
What is Auto-run and is it safe? Auto-run (formerly “Yolo mode”) lets the agent run terminal commands without confirming each one, gated by a natural-language allow-list you write. It is safe for build, test, lint, and codegen commands. Keep it off for destructive or production-adjacent commands, and review the diff before you commit.
The build only fails in CI, never on my machine. Why?
You are almost certainly in cause 5 or 6: a stricter tsconfig.build.json, a missing env var/secret, a missing fixture file, or a Node/pnpm version gap. Reproduce CI locally with tsc -p tsconfig.build.json --noEmit and a clean pnpm install, and check that every new env var is in .env.example and the CI secrets.
Composer “fixed” each error but new ones keep appearing. What now?
That is cascade chasing. Stop patching individual lines. Roll back to the last green commit, reapply the change as one unit, and let Auto-run drive pnpm build to completion so the agent fixes the root cause once instead of treating symptoms.