Skip to main content

Command Palette

Search for a command to run...

Debugging with Cursor

Debugging is detective work: trace the error, understand the context, form a hypothesis, test it. Cursor does much of this work for you. It reads stack traces, searches your codebase for relevant code, proposes fixes, and runs tests to verify them.

For tricky bugs that need runtime information, Debug Mode takes this further: it generates hypotheses, instruments your code with logging, and uses the actual runtime data to pinpoint root causes.

Debug Mode: runtime-driven debugging

Debug Mode is designed for bugs that are hard to reproduce or understand. Instead of immediately writing a fix, the agent forms hypotheses about what could be wrong, adds logging to test those hypotheses, then asks you to reproduce the bug so it can see what actually happens at runtime.

This matters because many bugs are not obvious from reading code. A race condition, a memory leak, an intermittent failure: these require seeing what the code actually does, not what it looks like it should do. Debug Mode bridges that gap by collecting real execution data.

When to use Debug Mode

Debug Mode works best for:

  • Challenging bugs or regressions that can be reproduced
  • Performance problems and memory leaks
  • Issues where reading the code does not reveal the cause

For straightforward errors with clear stack traces, regular Agent mode is faster. Use Debug Mode when you have tried the obvious fixes and they did not work, or when you need to understand what is actually happening at runtime.

Switch to Debug Mode with Shift+Tab and select Debug.

The Debug Mode workflow

Debug mode example: Debug a reproducible issue
The checkout flow is failing for some users but not others. I can reproduce it by logging in as user test@example.com and adding 3 items to the cart.
  1. Describe the bug: Tell Cursor what is happening and how to reproduce it. Include specific steps, user accounts, or data that triggers the issue. The more detail you provide, the better the instrumentation.

  2. Agent explores and hypothesizes: Cursor reads your codebase and generates multiple hypotheses about what could be wrong. Some will be obvious; others will be approaches you would not have considered.

  3. Agent adds instrumentation: Cursor adds logging statements designed to test its hypotheses, capturing variable states, execution paths, and timing information.

  4. You reproduce the bug: Go to your application and trigger the bug while the agent collects runtime logs. This keeps you in the loop and ensures the agent captures real behavior, not simulated behavior.

  5. Agent analyzes and fixes: With real data about what happened, Cursor pinpoints the root cause and generates a targeted fix. This is often just a few lines, not the hundreds of speculative changes you might get without runtime data.

  6. You verify: Reproduce one more time to confirm the fix works. If not, the agent adds more logging and refines its approach.

This human-in-the-loop verification matters. Sometimes a fix works technically but does not feel right, or fixes the symptom without addressing the underlying problem. You make that call, not the agent.

Debug mode example: Race condition
There's a race condition somewhere in the order processing. Orders occasionally get duplicated. I can reproduce by rapidly clicking the submit button.

Starting from an error

The most common debugging scenario: you have an error and need to find the cause. Cursor works best when you give it everything you have.

Agent example: Debug from error
I'm seeing 'TypeError: Cannot read property id of undefined' at UserService.getProfile (line 45). Find the root cause and fix it.

Stack traces tell Cursor where to look, but the root cause is often upstream. The error occurs at line 45, but the problem might be in whatever called that function with bad data. Cursor traces through callers to find where things went wrong, not just where the error surfaced.

For log-based debugging, paste the relevant output and let Cursor correlate timestamps and events:

Agent example: Debug from logs
Order processing is failing for order 12345. Logs show inventory check passed, then payment authorization started, then the error. Find where it fails after payment auth.

The key is giving Cursor enough context. Error messages alone are often ambiguous. Stack traces narrow it down. Logs with timestamps let Cursor see the sequence of events. Steps to reproduce let Cursor verify fixes actually work.

Debugging from support tickets

When users report bugs through support channels, you often start with incomplete information: a description of what went wrong, maybe a screenshot, sometimes account details. Cursor helps you investigate these issues systematically.

Agent example: Investigate support ticket
A customer reports: 'I tried to export my data but got a blank file. I'm on the Pro plan, account ID 12345.' Find the export functionality, check what could cause blank exports, and identify likely causes for this user's issue.

Start by having Cursor locate the relevant code and identify potential failure points. Customer descriptions are often symptoms rather than root causes. A "blank file" could mean the export ran but found no data, hit a timeout, failed silently, or succeeded but the download was corrupted. Cursor can map out these possibilities and suggest what to check first.

For issues that require account-specific investigation, give Cursor the context it needs:

Agent example: Account-specific investigation
Support ticket: User can't see their team members after being added to an organization. Account: user@company.com, Org ID: org_789. Check the team membership logic, permission checks, and any caching that might delay visibility.

When you have access to logs or monitoring dashboards, share what you find:

Agent example: Debug with logs
User was added to org_789 via admin panel but their JWT still shows org_456. They're getting an empty team members list. Find where we set org_id in the token and why it's not updating after org changes.

Cursor can correlate timestamps, identify the discrepancy, and trace through your authentication and session code to find where the stale data originates.

Building a support debugging workflow

For teams handling regular support escalations, create a rules file that captures your debugging patterns:

Rules example: Support Debugging Context
# Support Debugging Context## Common issue categories- "Can't log in" -> Check auth provider status, then session/token issues- "Missing data" -> Check permissions first, then sync status, then data integrity- "Slow performance" -> Get timestamp range, check for N+1 queries or missing indexes## Useful queries- Find user by email: SELECT * FROM users WHERE email = ?- Check org membership: SELECT * FROM org_members WHERE user_id = ?- Recent errors for user: Check error_logs table with user_id filter## Access notes- Production logs in Datadog, filter by user_id tag- Admin panel at /internal/admin for account lookups- Feature flags checked via LaunchDarkly dashboard

This context helps Cursor suggest relevant investigation steps and know where to look for information specific to your infrastructure.

The iterative debugging loop

Cursor can run your code, see the results, and iterate. This closed-loop debugging is where Cursor is most effective.

Agent example: Run and fix
Run the test for UserService.getProfile. If it fails, fix the issue and run it again. Keep going until it passes.

The first fix often reveals a second issue. That is normal. Iterative debugging handles this naturally: run, observe, fix, repeat. This is faster than trying to anticipate every problem upfront.

For bugs that only occur under specific conditions, have Cursor write a test that reproduces the scenario:

Agent example: Reproduce and fix
This bug happens when a user has no email set. Write a test case that reproduces this scenario, then fix the code to handle it gracefully.

Creating a failing test first ensures two things: you have confirmed the bug exists, and you will know when it is fixed. This is more reliable than manual verification for edge cases.

Debugging frontend issues

Cursor's browser tool lets it see what users see: the rendered UI, console errors, network requests, and application state.

Agent example: Visual debugging
Open the checkout page and click 'Submit Order'. The button doesn't respond. Take a screenshot, check console errors, and identify the issue.

Frontend bugs often span multiple layers. A button that does not respond could be a JavaScript error, a CSS issue covering the element, a failed API call, or state that never updated. Cursor can check all of these by inspecting the actual browser state rather than guessing from code.

For performance issues, Cursor can profile network requests:

Agent example: Network debugging
The orders page is loading slowly. Check what API calls it makes, how long each takes, and identify any that are slow or failing.

Long-running investigations

Some bugs require extended investigation: flaky tests, memory leaks, race conditions that only appear under load. Cursor can work on these while you do other things.

Agent example: Debug flaky test
This test is flaky. It passes sometimes and fails others. Run it 20 times, collect the failures, and find the pattern. What's causing the inconsistency?

Flaky tests are particularly suited to this approach. The pattern often only emerges after many runs, and manually running a test 20 times is tedious. Cursor can do the repetitive work and surface the insight.

For long debugging sessions, give clear success criteria ("the test should pass consistently 20 times in a row"), make sure Cursor can run the relevant tests, and check in periodically. The agent will keep iterating until it meets the criteria or gets stuck.

Understanding before fixing

For unfamiliar code, understanding comes before fixing. Jumping straight to a fix in code you do not understand often creates new bugs or fixes the symptom without addressing the cause.

Ask mode example: Understand before debugging
Before we try to fix this bug, explain how the OrderProcessor class works. What are its main responsibilities? What other services does it depend on? What calls it?

Use Ask mode for this exploration. Ask Cursor to explain the flow, identify the components involved, and map out what could go wrong. Then switch back to Agent mode with a clearer picture of where to focus.

This is especially valuable when debugging code someone else wrote, or code you wrote long enough ago that you have forgotten the details.

Root cause analysis

Finding the immediate fix is often not enough. Without understanding why the bug happened, similar bugs will keep appearing.

Ask mode example: Find root cause
You fixed the null reference error. Now explain why this happened. How did we get into a state where user.profile was undefined? What sequence of events leads here?

After fixing a bug, ask Cursor to find other places with the same pattern. If the bug was a missing null check, there may be similar missing checks elsewhere. If it was a race condition, the same race might exist in related code.

Document significant findings in your rules files or team documentation. The best debugging session is the one you do not have to repeat.

Building a debugging knowledge base

Capture what you learn so debugging knowledge persists across sessions and team members.

Create a .cursor/rules/debugging.mdc file:

Rules example: Debugging Context
# Debugging Context## Common issues- Null user.profile: Usually means the user was deleted but sessions weren't cleared- Payment timeout errors: Check the payment gateway status page first- Slow API responses: Often caused by N+1 queries, check the query logs## Useful commands- npm run debug:payments - Runs payment service with verbose logging- docker logs worker -f - Follow worker logs for background job issues- npm run db:query-log - Shows recent slow queries## Known flaky tests- tests/integration/checkout.test.ts - Race condition in cart clearing, fix in progress- tests/e2e/notifications.test.ts - Timing dependent on email service mock## Debugging tips- Always check if the issue reproduces locally before diving in- The staging database resets nightly; check if data-dependent bugs are timing related- Payment sandbox credentials expire monthly; check if payment tests suddenly fail

Update this file as you learn. When you solve a tricky bug, add the symptoms and solution. When you discover a useful debugging command, document it. This file becomes institutional knowledge that helps Cursor (and your team) debug faster over time.

Getting started

  1. For tricky, reproducible bugs, use Debug Mode. It instruments your code, collects runtime logs, and uses actual data to find root causes instead of guessing from static code.

  2. Paste the full error. Stack traces, logs, error messages. The more context Cursor has, the faster it finds the issue.

  3. Let Cursor run code. Debugging is iterative. Let Cursor run tests, see failures, and try fixes rather than reviewing proposals without executing them.

  4. Use Ask mode first for unfamiliar code. Understand the code before trying to fix it. Ask Cursor to explain the flow and identify potential issues.

  5. Document what you find. Add debugging knowledge to rules files so Cursor (and your team) can reference it next time.