·

Real World Workflow Error Investigation And Fix Deployment

Real World Workflow Error Investigation And Fix Deployment

This topic ties together everything in the module into a complete, end-to-end workflow: from the moment a Sentry alert fires, through AI-driven investigation and root cause analysis, to a GitHub PR with the fix linked back to the Sentry issue. This is not a toy example — every step reflects how production teams operate, and every prompt and command is copy-paste ready.

The scenario: your payment service is throwing UnhandledPromiseRejectionWarning errors in production. Sentry has grouped them under issue PAY-4892. The alert just fired in your Slack channel. Let's fix it.


Workflow Overview: From Sentry Alert to Deployed Bug Fix

The full workflow consists of four phases. Each phase has a clear input, tool, and output:

Phase 1: Data collection
  Input: Sentry issue ID (PAY-4892)
  Tool:  Sentry MCP (via Claude Code, Cursor, or Gemini CLI)
  Output: Event payload — stack trace, breadcrumbs, request context, user data

Phase 2: Root cause analysis
  Input: Event payload + local source code
  Tool:  AI agent (with filesystem access)
  Output: Root cause hypothesis + proposed code fix

Phase 3: Fix implementation and testing
  Input: Proposed fix + existing test suite
  Tool:  AI agent (code editing + terminal)
  Output: Applied code change + regression test

Phase 4: PR creation and Sentry linkage
  Input: Applied fix + Git branch
  Tool:  GitHub CLI (gh) + Sentry API
  Output: GitHub PR linked to Sentry issue

Before starting, confirm your setup is ready:

claude mcp list

gh auth status

git status
git checkout main && git pull origin main

Tips
- Have the Sentry issue ID ready before you start — copy it from the alert notification (Slack, PagerDuty, email). Every prompt in this workflow references the issue ID, so having it ready speeds up the session.
- Create a new Git branch before starting any investigation that may produce code changes. Starting clean prevents accidental commits to main.
- Keep a scratchpad open alongside your AI client. Paste key findings (root cause hypothesis, affected file paths, test names) as you discover them — you'll reference them in later prompts.
- Run git stash if you have uncommitted changes before starting. A dirty working tree confuses the agent when it tries to apply fixes and create diffs.


Step 1: Pulling the Error Event, Stack Trace, and Breadcrumbs via MCP

The first phase is pure data collection. The goal is to understand what happened — not to jump to a fix. Resist the urge to ask for a fix in the first prompt.

Create a working branch:

git checkout -b fix/sentry-pay-4892

Prompt 1 — Issue overview:

Get Sentry issue PAY-4892. Give me:
1. The full exception type and message
2. The culprit function and file
3. Event count (total and in the past 24 hours)
4. First seen and last seen timestamps
5. Whether this issue is linked to a specific release

Prompt 2 — Deep event analysis:

Get the most recent event for Sentry issue PAY-4892. Show me:
1. The complete stack trace — all frames, including non-app frames. Mark which frames are in-app.
2. All breadcrumbs in chronological order with timestamps and log levels
3. The HTTP request: method, URL, headers (redact Authorization values), body if present
4. The user context: user ID, IP address (truncated), any custom user tags
5. Any extra data attached to the event (custom tags, context objects)

Prompt 3 — Historical pattern check:

Get 3 more events from Sentry issue PAY-4892 (different from the first one you fetched). For each event, note:
- The user ID
- The request URL and method
- The values of local variables at the top in-app stack frame if available
Are there patterns across these events? Same endpoint? Same user segment?

Prompt 4 — Correlate with releases and deployments:

Check the Sentry releases for project "payment-service". When did PAY-4892 first appear? Does it correlate with a specific release version? List the 3 releases closest to the firstSeen date of this issue.

At the end of Step 1, you should have documented:
- Exact exception type and message
- The file and line number that threw
- The common request path that triggers the error
- The release version where the bug was introduced

Tips
- Always fetch multiple events (3-5), not just one. A single event may be anomalous. Patterns across events reveal the true root cause.
- Save the event payload summary to a file: in Claude Code, say "write a summary of PAY-4892 to /tmp/sentry-pay-4892-summary.md". This gives you a persistent reference.
- If the breadcrumbs are long (50+ entries), ask the AI to "show only breadcrumbs from 30 seconds before the error timestamp." This focuses on the causal window.
- Check whether the error has user.id populated. If not, it may be hitting anonymous/unauthenticated paths, which narrows the attack surface significantly.


Step 2: AI Root Cause Analysis and Code Fix Proposal

With the Sentry data in hand, you now use the AI to reason about the codebase. This step requires file access in your AI client.

Prompt 5 — Open the offending code:

The Sentry stack trace for PAY-4892 points to:
  File: src/services/payment.service.ts
  Function: PaymentService.processPayment()
  Line: 87

Read this file from the current project. Show me the function starting from the function declaration down to at least line 100. Also read any files it imports that are relevant to the error.

Prompt 6 — Cross-reference Sentry data with source code:

Here is what the Sentry event shows:
- Exception: UnhandledPromiseRejectionWarning: TypeError: Cannot read properties of undefined (reading 'amount')
- Stack frame: PaymentService.processPayment() at payment.service.ts:87
- Breadcrumbs show: POST /api/v1/payments was called with body: {"currency": "USD"} — note: no "amount" field

Looking at the code you just read, explain exactly why the TypeError occurs on line 87 when the request body is missing the "amount" field.

Prompt 7 — Root cause confirmation and fix proposal:

Based on the Sentry data and the source code:
1. State the root cause in one clear sentence
2. Explain why this path wasn't caught before (missing validation? missing test coverage?)
3. Propose a minimal fix — change only what is necessary to prevent the error
4. Show the fix as a diff against the current code
5. Confirm your fix handles the edge cases seen across all the events you reviewed

Expected output:

// payment.service.ts
 async processPayment(payload: PaymentPayload): Promise<PaymentResult> {
+  if (!payload.amount || payload.amount <= 0) {
+    throw new ValidationError('Payment amount is required and must be positive');
+  }
   const charge = await this.stripeClient.charges.create({
     amount: payload.amount * 100,  // line 87 — was reading undefined.amount
     currency: payload.currency,

Prompt 8 — Write a regression test:

Write a Jest test for PaymentService.processPayment() that:
1. Tests the happy path with a valid payload
2. Tests the exact error case from PAY-4892: a payload with "currency" but no "amount"
3. Tests a payload with amount = 0
4. Expects the new ValidationError to be thrown for invalid inputs

Place the test in the appropriate test file for this service (check the existing test structure in the project).

Apply the fix:

Apply the fix to src/services/payment.service.ts and add the new tests to the appropriate test file. Then run the tests with: npm test -- --testPathPattern=payment

Tips
- The "root cause in one sentence" constraint is important — it forces precision. If the AI can't state it in one sentence, it doesn't fully understand the cause yet.
- Ask the AI to check whether the same pattern (missing input validation) appears in sibling functions. This often reveals that a systematic fix is better than a one-line patch.
- Review the proposed diff yourself before applying. The AI may propose a fix that's correct for the reported case but introduces a behavior change in edge cases you care about.
- When the fix involves adding error throwing, ask: "What error type should this throw? Should it be a 400 Bad Request at the HTTP layer or a ValidationError in the service layer?" Architecture consistency matters.


Step 3: Opening a GitHub PR with the Fix Linked to the Sentry Issue

With the fix applied and tests passing, you're ready to create the PR. The PR should be traceable back to the Sentry issue so your team can close the loop.

Verify the changes:

git diff

npm test

git add src/services/payment.service.ts
git add src/services/__tests__/payment.service.test.ts

Prompt 9 — Write the commit message:

Based on the Sentry issue PAY-4892 and the fix you applied, write a Git commit message that:
1. Uses the format: "fix(payment): <brief description>"
2. Includes a body explaining what was broken and what the fix does
3. References the Sentry issue ID PAY-4892
4. Is under 72 characters for the subject line

Apply the commit:

git commit -m "fix(payment): validate amount field before processing charge

PaymentService.processPayment() would throw a TypeError when
the request body was missing the 'amount' field, because it
passed undefined directly to the Stripe client.

Added input validation at the service layer that throws a
ValidationError with a clear message for invalid payloads.

Fixes Sentry issue: PAY-4892"

Push the branch:

git push -u origin fix/sentry-pay-4892

Prompt 10 — Generate the PR description:

Write a GitHub pull request description for the fix to Sentry issue PAY-4892. Include:
1. A summary section: what was broken, what the fix does
2. A "Root cause" section with the one-sentence explanation
3. A "Testing" section: what tests were added and how to verify locally
4. A "Sentry" section: link to the issue (https://your-org.sentry.io/issues/PAY-4892/) and state that this fix should resolve it
5. A checklist: unit tests added, manual testing steps

Create the PR using GitHub CLI:

gh pr create \
  --title "fix(payment): validate amount field to prevent TypeError in processPayment" \
  --body "$(cat <<'EOF'
## Summary

- `PaymentService.processPayment()` threw `TypeError: Cannot read properties of undefined (reading 'amount')` when the request body was missing the `amount` field
- Added input validation at the service layer that throws a `ValidationError` before the Stripe client call
- Added unit tests covering the validation edge cases

## Root Cause

`processPayment()` assumed `payload.amount` was always present but had no guard against malformed requests missing the field, causing an unhandled TypeError that propagated to production.

## Testing

```bash
npm test -- --testPathPattern=payment

New test cases added:
- should throw ValidationError when amount is missing
- should throw ValidationError when amount is zero or negative
- should process payment successfully with valid payload

Sentry

  • Issue: PAY-4892
  • This fix adds the missing validation that caused the TypeError. After deployment, PAY-4892 should stop receiving new events.

Checklist

  • [x] Unit tests added for the bug case and edge cases
  • [x] Manual test: POST /api/v1/payments without amount field returns 400
  • [x] No breaking changes to existing API contract
    EOF
    )" \
    --base main \
    --head fix/sentry-pay-4892

**Link the PR back to Sentry** using the Sentry API to add a comment on the issue:

```bash
PR_URL=$(gh pr view --json url -q .url)

curl -X POST \
  -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"text\": \"Fix deployed in PR: $PR_URL\"}" \
  "https://sentry.io/api/0/issues/PAY-4892/comments/"

After the PR is merged and deployed, resolve the Sentry issue:

curl -X PUT \
  -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved"}' \
  "https://sentry.io/api/0/issues/PAY-4892/"

Verify the fix is holding post-deployment:

Check Sentry issue PAY-4892. Have there been any new events in the last 2 hours? What is the current event rate compared to before the fix was deployed?

Tips
- Use gh pr create --draft for fixes that need review before merging — this signals to reviewers that the PR is not yet merge-ready while still linking it to the Sentry issue.
- Set up a Sentry release tracking integration with GitHub (sentry.io/settings/integrations/github/) so that deployed PRs automatically link to Sentry issues via commit references. Once set up, including "Fixes PAY-4892" in the commit message will auto-resolve the issue on deploy.
- After the PR is merged, ask the AI one final time: "Given the fix for PAY-4892, are there any similar patterns in the codebase that should be addressed proactively? Search for other service methods that accept user-provided payloads without validation." This prevents the next Sentry alert.
- Document the full workflow in your team's runbook with the prompt templates from this topic. Standardizing the prompts ensures consistent investigation quality across team members and incident severities.