On this page
AI debugging works best when the assistant receives a small, reliable incident packet rather than an unfiltered wall of logs. A stack trace can identify where execution failed without explaining why the value became invalid. A plausible diagnosis is still only a hypothesis until a controlled check supports it.
The practical workflow is to preserve evidence, minimise the reproduction and ask for competing explanations with discriminating tests. Keep the assistant focused on reducing uncertainty before it edits code. That approach is usually faster than trying a succession of confident patches against an unreliable reproduction.
Assemble a trustworthy incident packet
Start with expected and actual behaviour in separate sentences. Describe what the user attempted, what should have happened and the observable failure. Include the affected route, runtime, relevant dependency versions and whether the problem occurs locally, in staging or only in production. Record the build identifier so source references match the deployed code.
Provide exact reproduction steps, including prerequisite state. “Click Save” is incomplete if the bug requires an expired session, a slow response or an existing draft. State frequency honestly: every attempt, intermittent, or observed once. A failure that appears random may depend on timing or a hidden account permission.
Collect the exception type, message, complete relevant stack and nearby structured events. Preserve timestamps and request identifiers that connect those events. Do not copy an entire day of logs and ask the model to find the problem; select a bounded window and explain why it matters.
Before sharing, remove tokens, cookies, private request bodies and personal information. Sanitise consistently so the same request keeps the same replacement identifier across files. The OWASP logging guidance is a useful reference for deciding what should never appear in diagnostic output.
Interpret the trace in its runtime context
Read the first relevant application frame, but do not assume it is the origin of the defect. A property access can fail because an earlier adapter returned an unexpected shape. Distinguish the failure location from the point where an invalid state first entered the system.
For bundled browser code, verify source maps correspond to the deployed asset. A stale map can make a precise-looking line number actively misleading. The Chrome DevTools source-map documentation explains how authored sources relate to generated code. Check the mapping before feeding source snippets to the assistant.
Include asynchronous boundaries when available: the request that started the operation, the callback that resumed it and any cancellation signal. A stack alone may omit the event sequence that produced a race. Correlate events by operation rather than sorting unrelated requests into a single narrative.
If a network dependency appears involved, use the API latency tester against a safe, non-sensitive endpoint to gather comparative timing evidence. Record environment and test time, and do not submit private credentials to an external tool. A slow measurement can support a timing hypothesis, but it does not prove that latency caused the application error.
Ask for hypotheses and decisive checks
Tell the assistant to separate observations from assumptions. Request a ranked list of competing hypotheses, each with evidence for it, evidence against it and a cheap test that would change the ranking. This makes disagreement productive instead of turning the first explanation into an anchor.
A compact prompt helps impose that discipline:
Expected: saving an existing draft shows a confirmation.
Actual: the second save throws the attached TypeError.
Repro: sign in, open fixture draft, save twice without reload.
Attached: sanitised trace, correlated events, relevant adapter.
Do not edit code yet. Give three hypotheses and one targeted
check for each. Label missing evidence and avoid invented APIs.Prefer discriminating experiments over broad logging. If the hypotheses are a stale closure, malformed response and duplicate event handler, choose checks that distinguish them. Log the handler registration count, inspect the actual response shape and compare the captured value with current state. Do not add every conceivable log statement at once.
Use the AI coding assistants directory to compare repository-aware tools with clear permission boundaries. Give read access to the relevant code first. An assistant that can patch everything is not necessarily better at identifying what evidence is missing.
Build the smallest reliable reproduction
Reduce the failing scenario while keeping it observable. Replace the live API with a sanitised captured response, isolate the component or call the adapter directly. Remove unrelated styling and navigation only after confirming that the failure still occurs. Minimal reproduction means the smallest case that preserves the mechanism, not the smallest code snippet you can paste.
Control nondeterminism explicitly. Use a fixed clock for expiry behaviour, a seeded source where randomness matters and deferred promises for response ordering. Avoid relying on arbitrary delays to reproduce a race; those delays can make the test flaky without establishing the necessary sequence.
Keep a record of reductions that stop the failure. That information is evidence: removing a subscription may identify a lifecycle interaction, while replacing a response may reveal a schema mismatch. The assistant can help propose the next reduction, but you should run it and report the actual outcome.
For backend JavaScript, the Node.js debugging guide explains inspector-based investigation. Breakpoints and inspected values can resolve questions that another paragraph of speculation cannot. Never expose a debugger port publicly while trying to make an incident easier to investigate.
Patch the cause and verify the explanation
Once evidence supports a cause, request a bounded repair that addresses it without unrelated cleanup. A null check may stop an exception while hiding a broken contract. Decide whether the correct response is validation, a lifecycle fix, an explicit empty state or rejection of an invalid operation.
First add a regression test that fails for the observed reason on the defective version. Then apply the patch and check the result. The guide to AI-generated unit tests explains how to prevent a generated test from merely repeating the patch's assumptions. Include adjacent cases, such as first save, repeated save and cancellation during save.
Use production verification appropriate to risk: staged rollout, relevant error counts and confirmation that the intended journey still completes. A disappearance of exceptions is not success if the feature silently stops performing work. Track the user-visible outcome alongside the technical symptom.
Finish with a concise incident note: root cause, supporting evidence, exact changes, checks actually run and unresolved limitations. Remove temporary diagnostic output or convert useful events into safe structured telemetry. For larger cleanup discovered during the investigation, follow the small-step refactoring workflow in a separate change rather than expanding the emergency patch.
Key takeaways
- Provide sanitised traces, runtime context and reproducible steps together.
- Distinguish where an exception surfaced from where invalid state originated.
- Ask for competing hypotheses and tests that separate them.
- Control timing and dependencies when building a minimal reproduction.
- Verify both the regression fix and the real user outcome after deployment.
Reach designers & developers at work
Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.
Become a sponsor