Claude Code Bug Report Template: Turn Vague Bugs Into Reproducible Fixes
Use a practical Claude Code bug report template with repro steps, logs, failing tests, and PR handoff notes.
When Claude Code receives only “the page is broken” or “tests fail,” it has to guess. The first patch may look reasonable, but it often skips the root cause, the proof command, and the explanation reviewers need. A strong bug report turns vague pain into a reproducible debugging task.
This article gives you a practical template for Claude Code sessions: symptom, expected behavior, actual behavior, minimum reproduction, logs, environment, failing test, constraints, and PR handoff. Use it after the first task runbook, deepen the investigation with Claude Code debugging techniques, and finish with the PR quality checklist.
Official references worth keeping nearby are the Claude Code CLI reference, commands reference, common workflows, and GitHub Actions guide. They clarify when to use flags such as --verbose, commands such as /debug, and product feedback commands such as /feedback or /bug.
What a useful report contains
| Field | What to write | Why Claude Code needs it |
|---|---|---|
| Symptom | Page, command, route, or API where the bug appears | Entry point for investigation |
| Expected behavior | The business or UI rule that should hold | Definition of “fixed” |
| Actual behavior | Error text, status code, visual failure, wrong output | Facts, not guesses |
| Reproduction | The smallest path that fails within a few minutes | A way to prove hypotheses |
| Environment | OS, runtime, browser, branch, relevant env names | Local-vs-CI differences |
| Evidence | Logs, screenshots, stack traces, failing tests | Before/after proof |
| Constraints | Files that may or may not be touched | Smaller diffs |
| Handoff | Root cause, verification, risk, follow-up | Faster PR review |
The most common beginner mistake is omitting expected behavior. “Make the error go away” is not a requirement. Should the API return an empty list, a 400, a user-facing warning, or a retry? State the rule in a sentence that can be tested.
Copy-paste bug report template
Save this as bug-report.md, fill it in, and give it to Claude Code before asking for edits.
# Bug report for Claude Code
## Goal
- Bug to fix:
- Desired outcome:
- Out of scope:
## Environment
- OS:
- Node / package manager:
- Browser / device:
- Branch:
- Relevant env var names, not values:
## Symptom
- Where it happens:
- Who sees it:
- Frequency: always / intermittent / unknown
## Expected behavior
-
## Actual behavior
-
## Minimum reproduction
1.
2.
3.
## Evidence
- Error message:
- Logs:
- Screenshot:
- Failing command:
## Recent changes
- PR / commit:
- Likely files:
## Constraints
- Allowed scope:
- Do not touch:
- Do not paste secrets or customer data:
## Request to Claude Code
1. Do not patch immediately
2. List the top three hypotheses
3. Propose the smallest check that could disprove each hypothesis
4. Create a minimum reproduction or failing test first
5. Apply the smallest useful fix
6. Report verification commands and remaining risk
This works for internal tickets, support handoffs, and PR comments. The point is to tell Claude Code how success will be measured before it starts editing.
Collect context with a runnable script
It is easy to forget the branch name, Node version, or current diff. This dependency-free Node script collects the basics and masks obvious secrets.
// scripts/collect-bug-context.mjs
import { execFileSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { platform, release } from "node:os";
import { cwd } from "node:process";
function run(command, args) {
try {
return execFileSync(command, args, {
cwd: cwd(),
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
}).trim();
} catch (error) {
return `(failed: ${command} ${args.join(" ")})`;
}
}
function maskSecrets(text) {
return text
.replace(/(api[_-]?key|token|secret|password)=([^\\s]+)/gi, "$1=***")
.replace(/Bearer\\s+[A-Za-z0-9._-]+/g, "Bearer ***");
}
function readPackageScripts() {
if (!existsSync("package.json")) return "package.json not found";
const pkg = JSON.parse(readFileSync("package.json", "utf8"));
return JSON.stringify(pkg.scripts ?? {}, null, 2);
}
const report = {
generatedAt: new Date().toISOString(),
cwd: cwd(),
os: `${platform()} ${release()}`,
node: process.version,
branch: run("git", ["branch", "--show-current"]),
status: run("git", ["status", "--short"]),
lastCommit: run("git", ["log", "-1", "--oneline"]),
diffStat: run("git", ["diff", "--stat"]),
packageScripts: readPackageScripts(),
};
console.log(maskSecrets(JSON.stringify(report, null, 2)));
Run it like this:
mkdir -p scripts
# Save the code above as scripts/collect-bug-context.mjs
node scripts/collect-bug-context.mjs > bug-context.json
Use the output as evidence, not as a replacement for judgment. Do not paste real API keys, customer records, or full production logs.
Use case 1: Mobile CTA overflow
Weak report:
The mobile page is broken.
Useful report:
Symptom:
At /en/products/ with a 390px viewport, the pricing CTA overflows to the right.
Expected behavior:
The two CTAs stack vertically and no horizontal scroll appears.
Minimum reproduction:
1. Open Chrome DevTools at 390px width
2. Visit /en/products/
3. Scroll to the pricing section
Evidence:
document.documentElement.scrollWidth is 412
Screenshot attached
Constraints:
Do not change product links or copy. Inspect layout CSS only.
Now Claude Code can inspect width, gap, button copy, and parent containers. For monetized pages, also verify that the path to products and training still works after the fix.
Use case 2: Checkout API returns 500
API bugs need the request shape, expected response, actual error, and relevant configuration names.
Symptom:
POST /api/checkout returns 500 only when plan=pro.
Expected behavior:
Return 200 with a payment URL. If configuration is missing, fail with a clear setup error.
Actual behavior:
TypeError: Cannot read properties of undefined (reading 'prices')
Minimum reproduction:
curl -X POST http://localhost:3000/api/checkout \
-H "content-type: application/json" \
-d '{"plan":"pro"}'
Environment:
Uses STRIPE_SECRET_KEY and PRICE_PRO_ID. Do not paste values.
Constraints:
Do not add more real provider calls. Check config loading and input validation first.
Ask Claude Code to compare three hypotheses before editing: config loading, request validation, and price mapping. If the reproduction is local, the failing test can usually live at the handler or config-module level.
Use case 3: Date boundary regression
For timezone and month-end bugs, a failing test is better evidence than a screenshot.
import { describe, expect, it } from "vitest";
import { exportMonthlyOrderIds } from "../src/export-orders";
describe("exportMonthlyOrderIds", () => {
it("includes March orders and excludes April 1 UTC", () => {
const orders = [
{ id: "mar-start", createdAt: "2026-03-01T00:00:00.000Z" },
{ id: "mar-end", createdAt: "2026-03-31T23:59:59.999Z" },
{ id: "apr-start", createdAt: "2026-04-01T00:00:00.000Z" },
];
expect(exportMonthlyOrderIds(orders, "2026-03")).toEqual(["mar-start", "mar-end"]);
});
});
The instruction should be explicit: “Make this test fail first, then fix the implementation without relying on the local timezone.” The pitfall is patching only the UI date label while leaving the aggregation boundary wrong.
Investigation prompt for Claude Code
Read bug-report.md and bug-context.json.
Process:
1. Do not edit yet
2. Separate facts from guesses
3. Rank the top three root-cause hypotheses
4. Propose the smallest check that could disprove each one
5. Create a minimum reproduction or failing test first
6. After approval, make the smallest useful fix
Done means:
- The expected/actual gap is explained
- A failing test or reproduction command remains
- Verification commands are reported
- The PR handoff includes root cause, fix, risk, and follow-up
The official common workflows recommend giving Claude the error, the command that reproduces it, the steps, and whether it is intermittent. /debug is for diagnosing a Claude Code session. /feedback and /bug report issues with Claude Code itself. Keep those separate from bug reports for your own application.
PR handoff template
## Root cause
-
## Fix
-
## Regression coverage
- Added failing test:
- Manual reproduction checked:
## Verification
- [ ] npm test
- [ ] npm run typecheck
- [ ] npm run build
- [ ] mobile / desktop visual check if UI changed
## Risk
-
## Claude Code notes
- Hypotheses rejected:
- Files intentionally not touched:
- Follow-up issue:
This pairs well with the session handoff template and testing strategies. If your team uses Claude Code GitHub Actions, align issue comments and CI failure prompts with this same structure.
Pitfalls to avoid
Do not bundle unrelated bugs into one report. Login, checkout, and layout failures need separate reproductions.
Do not paste full logs. Include the twenty lines around the error, the request ID, and the reproduction command.
Do not finish without a failing test when the bug is about boundaries, data mapping, API contracts, or permissions.
Do not ask Claude Code to “look everywhere.” A small reproduction is more useful than broad permission to edit.
Do not skip the PR handoff. Reviewers need the root cause, proof, and residual risk.
Keep the monetization path in scope
On ClaudeCodeLab, a bug fix can break revenue routing if it changes CTAs, product cards, free PDF forms, Gumroad links, or consultation links. Treat those as part of the surface area when the article layout or product path changes.
For individual use, adapt the free checklist to your repository. If you want reusable prompts, review gates, and setup materials, visit products. If your team needs one shared process for bug reports, Claude Code permissions, PR review, and CI handoff, start with training.
Hands-on result
In hands-on testing, reports that included reproduction steps, expected behavior, a failing test, and PR handoff produced smaller Claude Code diffs and fewer reviewer questions than vague “please fix” prompts. The biggest improvement came from asking for three hypotheses before editing. It made wrong theories cheap to discard and moved the session from patching toward disciplined debugging.
Free PDF: Claude Code Cheatsheet
Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.
We handle your data with care and never send spam.
Level up your Claude Code workflow
Start with the free PDF, use Gumroad guides when you need repeatable workflows, and book consultation when rollout or revenue paths need human judgment.
About the Author
Masa
Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.
Related Posts
Claude Code Permission Safety Ladder: Expand Access Without Losing Control
A beginner-friendly ladder for moving Claude Code from read-only to limited edits, proof commands, and deploy checks.
Claude Code Small PR Proof Pack: Make Tiny Changes Reviewable
A practical proof pack for Claude Code PRs: diff, checks, public URL, CTA path, and rollback note.
Claude Code Review Gate Before Commit: Diff, Tests, Public URL, and CTA Checks
A commit-time review gate for Claude Code work: diff scope, build, public URL, revenue CTA links, missing tests, and unrelated files.
Related Products
50 Battle-Tested Claude Code Prompt Templates
Copy, paste, ship. 50 production-ready prompts.
Use proven prompts for code review, refactoring, testing, documentation, debugging, architecture, and incident response.
The Complete Claude Code Setup & Configuration Guide
From install to team-ready workflow.
A practical guide to installation, CLAUDE.md, hooks, MCP servers, permissions, IDE setup, and CI/CD workflows.