Use AI to Find Bugs Without Trusting Every Suggestion
AI can help you spot suspicious code, explain likely failure paths, and suggest focused tests. Use it as a reviewer, not an authority: give it a small, relevant excerpt, then verify each claim against the code, tests, and documented requirements before changing anything. You will need a working copy of the project and a way to run its checks.
What You’ll Need
- The code or a small, reproducible excerpt, plus the relevant language, framework, and dependency versions.
- A written description of what the code is supposed to do, including important input and edge cases.
- A development environment where you can run the project’s tests, formatter, and static-analysis tools.
- An AI coding assistant approved for your work. Check its data-handling terms; do not paste secrets, private customer data, credentials, or code you are not allowed to share.
Step-by-Step
- Start from a safe, reproducible state. Save or commit your current work so you can compare changes and revert them. Run the existing tests and relevant checks before asking for help. Record failures that already exist; otherwise, it is easy to mistake an old problem for a new discovery. If there are no tests, note that limitation.
- Choose a narrow target. Select one function, module, or small change rather than asking an AI to review an entire repository at once. Include its callers or related definitions only when they affect the behavior. A focused prompt makes it easier to check whether the response matches the actual code.
- Give context and ask for evidence. State the language and versions, intended behavior, known constraints, and relevant tests. Ask for possible defects, the input or state that triggers each one, the expected versus actual outcome, and the exact code path supporting the claim. Ask it to separate confirmed observations from assumptions and to suggest tests before proposing a patch.
- Review the code yourself before accepting a finding. Follow the cited path in your editor. Check types, control flow, error handling, data boundaries, and how the function is called. Verify that the behavior the assistant calls a bug really conflicts with a requirement. If it cannot identify a trigger or a concrete consequence, treat the claim as unverified, not as a defect.
- Reproduce plausible problems. Build a small test or example for the exact conditions described. Use the project’s normal test framework and include boundary cases such as empty input, the smallest and largest valid values, invalid data, repeated calls, or failures from dependencies where relevant. A failing test that demonstrates the unwanted behavior is stronger evidence than a persuasive explanation.
- Check competing explanations. Look for validation performed by a caller, documented library behavior, invariants, or platform assumptions the AI may have missed. Consult the source, official documentation, and existing project conventions. Ask a follow-up question about a specific uncertainty, but do not treat a second AI answer as independent proof.
- Make the smallest justified change. Prefer a targeted fix over a broad rewrite. If the AI provides a patch, inspect every changed line and understand why it is needed. Reject unrelated formatting, dependency updates, or refactors unless you separately intend to make them.
- Run checks and inspect the final diff. Run the new regression test and the relevant existing tests, type checks, linter, and build. Review the diff for accidental edits, exposed data, changed interfaces, and tests that merely repeat the implementation rather than checking behavior. If a check fails, compare it with the baseline before blaming the fix.
- Document the result. Record the bug’s trigger, the behavior that was wrong, the test that reproduces it, and what the fix changes. Mark unsupported AI suggestions as rejected or unresolved instead of silently turning them into code. This keeps later reviewers focused on evidence.
Common Mistakes
- Asking for a complete review with little context: broad prompts encourage generic warnings and missed assumptions. Narrow the scope and state the intended behavior.
- Accepting confident wording as proof: plausible explanations can rely on nonexistent APIs, wrong language semantics, or assumptions about callers. Verify the cited behavior in the actual project.
- Changing code before writing a reproducer: without a test or clear reproduction, you may fix the wrong issue or introduce a regression. Capture the failure first whenever practical.
- Testing only the suggested example: a patch may pass one happy-path case but fail at boundaries or under errors. Add cases that target the condition and nearby edge cases.
- Sending sensitive code to an unapproved tool: remove credentials and personal data, and follow your organization’s rules for external services. Redact carefully; secrets can also appear in logs and configuration.
- Letting the tool rewrite unrelated code: a large diff hides risk and makes review harder. Keep bug fixes small and separate cleanup into its own change.
Tips
- Ask for a ranked list with severity, likelihood, triggering input, and a test idea. Treat the ranking as a starting point, not a reliable measure of impact.
- Request a “findings only” first pass, then ask for a patch after you have independently confirmed a defect. This reduces pressure to accept a solution just because it is available.
- Use deterministic tools first where possible: compiler errors, static analysis, linters, dependency checks, and existing tests can provide reproducible evidence.
- Keep prompts free of secrets and include only the code needed to understand the behavior. Replace private values with clearly labeled placeholders without changing relevant logic.
- For concurrency, security-sensitive logic, or data migrations, seek an appropriate human review. AI output and passing tests do not establish that every risk has been found.
- Preserve the exact prompt and finding for important changes. This helps reviewers distinguish the original evidence from later interpretations.
Troubleshooting
The AI reports a bug you cannot reproduce: ask it to state the exact preconditions and trace each step through the code. Check whether a caller or validation layer rules them out. If you still cannot verify the path, label the report unconfirmed and do not change code solely to silence it.
The response is vague or generic: provide a smaller excerpt, the expected behavior, and one failing input if available. Ask for file or function names and a concrete test case. Do not share extra private context just to make the response longer.
The suggested fix breaks tests: revert or isolate the patch, inspect the first meaningful failure, and compare against the baseline. The proposed fix may be wrong, or it may reveal an existing assumption that needs clarification. Do not disable a test simply because it fails.
Tests pass but you remain unsure: tests only cover the cases they exercise. Add a test for the reported trigger, review the relevant callers and invariants, and use static analysis or a human reviewer when the consequence could be serious.
The tool invents a function or library behavior: check the project’s installed version and authoritative documentation. Remove any patch based on an API that does not exist in your environment.
Frequently Asked Questions
Can AI find bugs that tests miss?
It can suggest overlooked paths and edge cases, but it can also miss real defects or invent them. Treat its output as a source of hypotheses to verify.
Should I paste my whole codebase?
No. Start with the smallest useful excerpt and include relevant callers or definitions only when needed. Follow your organization’s rules and the tool’s data-handling terms.
What should I ask the AI to include?
Ask for the suspected defect, its trigger, the expected and actual behavior, evidence in the code, assumptions, and a test that could confirm or disprove it.
Is a passing test enough to accept a suggestion?
No. A test can be incomplete or encode the wrong requirement. Check that it reproduces the intended failure and review the patch’s full impact.
Should I ask a second AI to verify the first?
You can use another review as an additional source of ideas, but its agreement is not independent proof. Confirm claims with code, documentation, tests, and review.
What if I cannot reproduce the reported issue?
Ask for more precise preconditions and check callers, configuration, and environment assumptions. Keep it marked unverified until you find evidence; avoid speculative changes.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.