Debugging and Error Recovery
PLError recovery in Cursor means undoing an agent change that broke the build or behaviour, then redoing the work under tighter constraints. Checkpoints roll back the agent’s file edits inside one chat, git commits protect everything between chats, and the recovery is accepted only when the build, tests, and a scoped diff agree, not on the agent’s word.
This page is for a developer who has built a first feature with Cursor’s agent and has now watched it go wrong. The agent refactored your authentication module, moved functions between files, and added a validation layer. The tests pass, but the login page renders blank in the browser. You ask it to fix that, it edits six more files, and now two tests fail that passed an hour ago.
What you get from a recovery routine in Cursor
Section titled “What you get from a recovery routine in Cursor”- A two-layer undo setup (checkpoints plus git) that you put in place before the agent starts
- A decision table for when to restore a checkpoint, when to reset to a commit, and when to fix forward
- Four copy-paste prompts: the fresh-chat diagnosis, the scoped fix, runtime instrumentation, and the pre-PR gate
- The git commands that measure what the agent changed without reading the whole diff
- Recovery steps for the six ways recovery itself goes wrong
Why agent-made breakage needs a different recovery
Section titled “Why agent-made breakage needs a different recovery”Agent mistakes rarely look like typos. They look like finished work.
| Typical human bug | Typical agent bug |
|---|---|
| Typo or off-by-one error | Code that compiles and type-checks but does the wrong thing |
| Forgotten edge case | A confident wrong assumption about a requirement |
| Copy-paste slip | A pattern from one part of the codebase applied where it does not fit |
| One broken function | Edits spread across many files, some of them unrelated to the task |
Two consequences shape everything below. First, a passing build proves little, so you need evidence from behaviour: a test that reproduces the bug, or runtime logs. Second, the agent’s own account of what it changed is not reliable, so you measure the change with git instead of reading the chat.
Set up two undo layers before the agent starts
Section titled “Set up two undo layers before the agent starts”Cursor keeps checkpoints of the agent’s file edits within a chat, so you can go back to the state before a given response. They are stored locally and separate from git, and restoring one reverts files only (Cursor’s agent overview, checked 2026-10-12). Git is the layer that survives a closed chat, a restarted editor, and a teammate’s machine. Use both.
-
Start every agent task from a clean tree on its own branch. In a terminal:
Terminal window git status --short # must print nothing; commit or stash firstgit switch -c fix/login-blank-page -
Commit at every milestone the agent finishes, not only at the end. For a feature built in phases, that means one commit after the schema, one after the API, and one after the UI:
Terminal window git add -A && git commit -m "wip: API endpoints pass their tests" -
Before a risky prompt (a refactor, a dependency upgrade, a migration), commit again. The commit, not the checkpoint, is your restore point if the editor closes or the chat is lost.
-
Know what a checkpoint cannot undo. Anything the agent did through the terminal is outside the file snapshot: a migration applied to your local database, a package installed, a file generated by a script. Treat those as not covered and undo them by hand.
Whether the agent asks you before each terminal command depends on the run mode you set under Settings > Agents > Approvals & Execution: Auto-review, Allowlist or Run Everything. Allow your test, lint, and build commands to run without a prompt rather than lifting approval for every command. See essential configuration for the setup.
Should you restore a checkpoint, reset to a commit, or fix forward?
Section titled “Should you restore a checkpoint, reset to a commit, or fix forward?”Pick the smallest undo that removes the damage.
| Situation | Undo with | Why |
|---|---|---|
| The last agent response made things worse, and earlier responses were fine | Restore the checkpoint from before that response | Removes one step and keeps the rest of the session’s work |
| Several responses in a row went wrong, or you cannot tell which one broke it | Keep a copy: git stash push -u -m "agent attempt" (this also cleans the tree). Discard: git restore --staged --worktree . back to your last commit, then git clean -nd to list files the agent created and git clean -fd to delete them | The commit is a known-good state; the checkpoint trail may not be |
| The chat is gone, Cursor restarted, or the change was already committed | git reset --hard LAST_GOOD_COMMIT on your branch, then git clean -nd and git clean -fd for files the agent created. If you already pushed, run git revert AGENT_COMMIT instead. LAST_GOOD_COMMIT and AGENT_COMMIT are hashes from git log --oneline | Only git has the history at this point |
| One piece is wrong and the rest is correct and tested | Fix forward with a scoped prompt (below) | Redoing good work costs more than fixing one part |
| The prompt itself was wrong or incomplete | Reset (and git clean -fd), then start a new chat with a better prompt | Fixing forward keeps building on a wrong premise |
Stop an agent that loops on the same error
Section titled “Stop an agent that loops on the same error”The pattern: the agent changes something, the test fails, it tries another approach, fails again, and starts repeating itself or undoing its own earlier fix. More prompts in the same chat rarely help, because the context now holds several failed approaches that pull the next attempt toward them.
-
Stop the agent from the chat so it does not keep editing.
-
Restore the checkpoint from before the loop started, or run
git restore --staged --worktree .to go back to your last commit, thengit clean -ndto list files the agent created andgit clean -fdto delete them. -
Find the cause yourself, or with the agent in Plan Mode, which plans before writing any code. Read the failing test’s actual output, not the agent’s summary of it.
-
Open a new chat and hand the agent the diagnosis, the file, and what it must not touch.
The last line matters. An agent told to stop after one failed attempt reports back instead of starting a new loop.
Rein in an agent that changed too many files
Section titled “Rein in an agent that changed too many files”You asked for a retry around one payment call and the agent also reformatted the billing module, renamed a helper, and touched three tests. Measure it first:
git diff --stat # files and line counts changed since the last commitIf the list holds files the task never needed, restore the checkpoint and constrain the scope in the prompt itself. Name the file, name the helper to reuse, and say what is off limits.
If the agent makes the same unwanted change in every session, the fix belongs in a project rule, not in each prompt.
When the tests pass but the feature is broken
Section titled “When the tests pass but the feature is broken”Static reading does not find this class of bug. The agent needs runtime evidence: what the code actually did, in order, on the failing path. Ask for temporary, tagged logging at each step, reproduce the bug yourself, and paste the output back. Cursor’s help describes Debug mode as for tricky bugs that need runtime evidence (checked 2026-10-12); in any other mode the steps are the same.
The tag makes cleanup checkable: git grep -n --untracked "DEBUG-LOGIN" must print nothing before you commit. For intermittent failures, race conditions, and regressions that need git bisect, follow the full workflow in AI-assisted debugging in Cursor.
Prove the recovery without reading every line
Section titled “Prove the recovery without reading every line”“All tests pass” from the agent is a claim. Accept the recovery on evidence that you can check in a minute, in this order.
-
The gate is green. Build, lint, type check, and tests run to completion in the terminal, not in the agent’s summary.
-
The scope is what you asked for.
git diff --stat main...HEADlists only the files the task needed. -
The tests were not weakened.
git diff main...HEAD -- '*.test.*' '*.spec.*'shows no deleted assertions, no new.skip, and no loosened expected values. An agent under pressure to turn a test green sometimes edits the test instead of the code; see protect the oracle. -
The debug code is gone.
git grep -n --untracked "DEBUG-"prints nothing. -
The original symptom is gone. Reproduce the bug the way you first saw it, or better, keep the failing test that reproduced it.
To make the gate automatic, run the test command and the DEBUG- grep from a Cursor stop hook that sends the agent back when either fails; see make Cursor re-run the gate. The agent can run the rest for you in one pass before you open the pull request.
You sign off on the pull request as its author, with the five checks above in its description. CI then runs the same gate, and an automated reviewer such as Bugbot plus a teammate review the pull request. How the team splits those checks is covered in version control and team collaboration in Cursor.
Should you fix forward or start over?
Section titled “Should you fix forward or start over?”Starting over is a deliberate choice, not a defeat. Use these as defaults and adjust to your codebase.
| Start over when | Fix forward when |
|---|---|
| The agent has failed at the same fix three times | The bug is small and isolated in otherwise good code |
| Understanding the tangled changes would take longer than redoing them | Most of the change is correct and already covered by passing tests |
| You realise the original prompt was wrong or incomplete | The work would be expensive to reproduce and one piece is wrong |
| The chat is long and keeps returning to failed approaches | The failure has a clear diagnosis you can hand over in one prompt |
To start over cleanly: reset to the last good commit, remove the agent’s new files with git clean -fd (preview with git clean -nd), open a new chat, write the prompt with explicit file limits and acceptance checks, and reference the plan file if Plan Mode produced one. Keep conversations short in general; context management covers why long chats degrade.
When the problem is Cursor, not the code
Section titled “When the problem is Cursor, not the code”Sometimes the agent is fine and the editor is not.
- The agent stops responding or errors on every request. Check your network and your plan’s usage, then pick a different model in the model picker to rule out one provider being down. See model selection.
- An MCP server fails or its tools disappear. Open the MCP server’s logs (see MCP setup in Cursor), fix the command or credentials they report, then restart the server or the editor.
- High CPU right after opening a large repository. Indexing is usually the cause and settles once it finishes. If it does not, exclude generated folders with an ignore file; see essential configuration.
- Work lost after a crash. Check
git stash listandgit reflogfirst. Committed work is recoverable from the reflog even after a hard reset.
What goes wrong when you recover from agent mistakes?
Section titled “What goes wrong when you recover from agent mistakes?”| Symptom | Cause | Recovery |
|---|---|---|
| Files are restored but the app still fails the same way | The agent ran a migration, install, or generator in the terminal, which the checkpoint does not cover, or created new untracked files that git restore --staged --worktree . leaves in place | Undo the side effect by hand (roll back the migration, reinstall from the lockfile with npm ci), list new files with git clean -nd and delete them with git clean -fd, then rerun the gate |
git reset --hard removed work you wanted | Uncommitted changes were not stashed | Committed work: git reflog. Staged but never committed: git fsck --lost-found sometimes finds it. Unstaged edits: restore a checkpoint if that chat is still open. From now on, run git stash push -u before every reset |
| The test is green, the bug is still there | The agent loosened the test instead of fixing the code | Restore the test from main with git restore --source main -- TEST_FILE (TEST_FILE is the path of the loosened test), then rerun the scoped-fix prompt with “do not modify tests” |
| A fresh chat makes the same wrong change again | The wrong assumption lives in the codebase or a stale rule, not in the old chat | Correct or add a project rule that states the convention, then retry |
| Tests pass alone and fail together after the fix | The agent introduced shared state: a module-level variable, an uncleared mock, a reused database connection | Ask the agent to find shared state between tests and isolate it; see testing patterns in Cursor |
| Debug logging reaches the pull request | Instrumentation was untagged, so nothing checked for it | Tag every temporary log line and make git grep -n --untracked "DEBUG-" part of the pre-PR gate |
Where to go next after error recovery in Cursor
Section titled “Where to go next after error recovery in Cursor”The Codex version of this page is error recovery in Codex.
Did this guide help you?
One tap, no sign-in.
What will you do with it?
How did it read?
What got in the way? Pick any that apply
Your role?
Thanks. I read every answer. Michał Jaskólski
Did this guide help?
One tap each. Close whenever you like.
no sign-in