One Claude Code Tip a Day: Build a Hypothesis Table Before Editing

Before Claude Code patches a bug, make it list competing hypotheses, evidence, checks, and the smallest next action. The table keeps debugging honest when the first theory sounds too convenient.

Abstract developer workstation with debugging hypotheses, evidence panels, terminal checks, and a verification grid

This post is part of the “One Claude Code Tip a Day” series — a daily guide to using Claude Code more effectively.

The real task: the first theory is usually too neat

A common Claude Code failure starts with a plausible diagnosis. You paste a bug report, Claude finds the first component that mentions the broken feature, and within two minutes there is a patch. The diff may even look reasonable. Then the focused test still fails, the browser still shows the old behavior, or production logs point somewhere else entirely. The problem was not that Claude was careless. The problem was that the session treated one attractive theory as truth before collecting evidence.

Today’s habit is to make Claude Code build a hypothesis table before editing. This is especially useful for debugging frontend bugs, flaky tests, API callbacks, deployment failures, and “works locally, fails in prod” issues. The table turns a vague debugging conversation into a small field investigation: what could be wrong, what evidence supports it, what would disprove it, and what is the smallest check to run next?

Start with a table, not a patch

When the task is a bug fix, resist the opening prompt “fix this.” Start with a read-only debugging contract:

`We have a bug where the checkout success banner does not appear after payment. Do not edit yet. Read the relevant route, state update path, and tests. Build a hypothesis table with columns: hypothesis, evidence already found, evidence missing, command or inspection to verify it, and smallest safe next action. Rank the rows by likelihood and risk.`

The important part is not the formatting. The important part is forcing Claude to keep multiple explanations alive. For the checkout banner, useful rows might include: the frontend never receives the success event, the API returns a pending status for one provider, the banner renders but CSS hides it, the redirect query parameter is dropped, or the Playwright test is racing the state update. A shallow session collapses these into “update the banner component.” A better session asks which row the evidence actually supports.

What a useful first answer looks like

A strong answer names files and proof commands. It might say: “The banner component is `apps/web/src/checkout/SuccessBanner.tsx`; payment state is set in `usePaymentResult.ts`; the callback route is `apps/api/src/routes/payments/callback.ts`; the focused check is `pnpm test:e2e --grep "checkout success"`; API evidence should come from the callback log line containing `provider_status`.” That answer gives you handles for inspection.

A weak answer says: “Possible causes include state, API, styling, or timing.” That is not useless, but it is generic. Push back immediately: `Rebuild the table using only evidence from files you have read or commands you can run. If a row is speculation, mark it as speculation and name the next check.` This second pass is where Claude Code becomes useful. You are not asking it to sound smart; you are asking it to attach every claim to a file, log, test, or browser observation.

Use the table to choose the next action

After the table, ask Claude to choose one row and justify the choice before editing:

`Pick the highest-value hypothesis to test first. Prefer a reversible check over a code change. Tell me exactly what command, log query, or browser inspection you will run. Do not patch until that check produces evidence.`

In a real session, Claude may discover that the frontend component is fine: the browser DOM contains no success event because the API callback normalizes one provider’s status incorrectly. The next action is not a CSS patch; it is a focused backend test or a log inspection. Or the table may reveal the opposite: the API response is correct, but a CSS rule makes the banner transparent on dark backgrounds. The table earns its keep by changing the path of the session before the diff grows.

Inspect after the first check

The first verification pass is rarely the end. Suppose Claude runs the focused Playwright test and it fails at the same assertion, but the screenshot shows the success banner briefly appears and disappears after a route refresh. That new evidence should update the table. Use a correction prompt:

`Update the hypothesis table with this test output and screenshot observation. Which hypothesis got stronger, which got weaker, and what is now the smallest safe patch? If the patch touches more than two files, explain why before editing.`

This prompt prevents the common spiral where every failed check becomes permission for a larger patch. The table is a living debug map. It should shrink uncertainty, not decorate a guess you already made.

Failure modes

The first failure mode is letting Claude create a table without reading code. That produces a consultant-style list of possibilities. Require file paths and commands. The second failure mode is overfitting to the first red test. A test failure is evidence, not the whole diagnosis; ask whether the failing assertion proves the product bug or only proves the test setup. The third failure mode is skipping disproof. Every row should include what would make Claude abandon that hypothesis.

Watch for another subtle problem: tables can become a way to delay action forever. The goal is not infinite analysis. The goal is one small, evidence-backed next move. If Claude has enough evidence to choose a row, make it act narrowly, run the check, and report the diff.

Rule of thumb

Use a hypothesis table when the bug could live in more than one layer: UI, API, data, tests, environment, or deployment. If Claude cannot fill the table with file-level evidence and verification commands, it is not ready to edit. If it can, let the highest-value row drive one small patch, then update the table from the result. Good Claude Code debugging is not “guess, patch, hope.” It is prompt, inspect, compare hypotheses, verify, correct, and only then widen the fix.