Skip to content

Workflow: Debugging with Debug Mode

Overview

This workflow covers systematic debugging using Cursor's Debug Mode, which generates hypotheses, adds instrumentation, and uses runtime data to find root causes.

When to Use: Tricky bugs, regressions, performance issues, race conditions


Prerequisites

  • Bug can be reproduced
  • Debug Mode available (Cmd+. → Debug)
  • Familiarity with Agent Modes

Workflow Diagram

StepAction
1. DescribeProvide symptoms, reproduction steps, expected behavior
2. ExploreAgent explores code, generates hypotheses
3. InstrumentAgent adds strategic log statements
4. ReproduceYou trigger the bug, logs are collected
5. AnalyzeAgent reviews logs, identifies root cause, fixes
6. VerifyConfirm fix works, remove instrumentation

Step 1: Describe the Bug

Enter Debug Mode and provide detailed information:

BUG DESCRIPTION
═══════════════
The order total sometimes shows incorrect values after applying
a discount code.

REPRODUCTION STEPS
══════════════════
1. Add items totaling $100 to cart
2. Apply discount code "SAVE20" (20% off)
3. Expected: $80 total
4. Actual: Sometimes shows $100, sometimes $80

FREQUENCY
═════════
Happens about 30% of the time

RELEVANT FILES
══════════════
@CartService.ts @DiscountService.ts @CheckoutController.ts

Step 2: Explore & Hypothesize

Agent explores the codebase and generates hypotheses:

HypothesisDetails
1. Race conditionDiscount applied after total calculated; async operations not properly awaited
2. Caching issueStale cart total cached; cache not invalidated after discount
3. State synchronizationFrontend state not synced with backend; multiple sources of truth

Most likely: Hypothesis 1 (race condition)


Step 3: Add Instrumentation

Agent adds targeted log statements:

typescript
// CartService.ts - Before
async calculateTotal(cartId: string): Promise<number> {
  const items = await this.getItems(cartId);
  return items.reduce((sum, item) => sum + item.price, 0);
}

// CartService.ts - With instrumentation
async calculateTotal(cartId: string): Promise<number> {
  console.log('[DEBUG] calculateTotal started', { cartId, timestamp: Date.now() });

  const items = await this.getItems(cartId);
  console.log('[DEBUG] items fetched', { count: items.length });

  const total = items.reduce((sum, item) => sum + item.price, 0);
  console.log('[DEBUG] total calculated', { total, timestamp: Date.now() });

  return total;
}

Logs are sent to Cursor's debug server for collection.


Step 4: Reproduce the Bug

Agent provides specific reproduction steps:

  1. Open the application in your browser
  2. Navigate to the cart page
  3. Add 2 items ($50 each)
  4. Apply discount code "SAVE20"
  5. Observe the displayed total
  6. Repeat 3-4 times to trigger the bug

Press Enter when you've reproduced the bug.

You execute the steps, triggering the bug. Debug server collects all logs.


Step 5: Analyze & Fix

Agent reviews collected logs:

Successful run (correct total):

10:30:00.100  applyDiscount started
10:30:00.105  discount applied to cart
10:30:00.200  calculateTotal started
10:30:00.210  items fetched with discount
10:30:00.215  total calculated: $80

Failed run (incorrect total):

10:31:00.100  applyDiscount started
10:31:00.101  calculateTotal started  ← Called too early!
10:31:00.105  discount applied to cart
10:31:00.110  items fetched WITHOUT discount
10:31:00.115  total calculated: $100  ← Wrong total

Root Cause: calculateTotal called before discount finishes

Agent proposes fix:

typescript
// CheckoutController.ts - Fix
async applyDiscountCode(code: string) {
  // Before: called concurrently
  // this.discountService.applyDiscount(code);
  // const total = this.cartService.calculateTotal();

  // After: properly awaited
  await this.discountService.applyDiscount(code);
  const total = await this.cartService.calculateTotal();

  return total;
}

Step 6: Verify & Cleanup

  1. Verify the fix:

    • Run reproduction steps again
    • Confirm bug no longer occurs
  2. Remove instrumentation:

    • Agent removes all debug log statements
    • Code returns to clean state
  3. Add regression test:

typescript
test('discount is applied before total calculation', async () => {
  const cart = await createCart([item50, item50]);
  await applyDiscount(cart.id, 'SAVE20');
  const total = await calculateTotal(cart.id);
  expect(total).toBe(80);
});

Best Practices

Provide Good Context

  • Detailed reproduction steps
  • Expected vs actual behavior
  • Frequency of occurrence
  • Relevant files and functions

During Reproduction

  • Follow steps exactly as given
  • Reproduce multiple times if intermittent
  • Note any variations in behavior

After Fixing

  • Always verify the fix works
  • Add test to prevent regression
  • Let Agent clean up instrumentation

When to Use Debug Mode

ScenarioUse Debug Mode?
Intermittent bug✅ Yes
Race condition✅ Yes
Performance issue✅ Yes
Memory leak✅ Yes
Simple typo/syntax error❌ No (use Agent)
Clear error message❌ No (use Agent)
Missing functionality❌ No (use Agent)

Built with VitePress | Powered by Claude AI