10 Prompts for Debugging and Finding Bugs in Code
Debugging is a universal struggle. Every developer has spent hours staring at an error message, hoping it would reveal its secrets. Modern AI assistants can dramatically accelerate this process, but the quality of the output depends on the quality of the prompt. A vague 'why is my code broken?' yields generic advice; a structured prompt can produce a precise diagnosis.
In this article, you'll find ten battle-tested prompts for common debugging tasks: reading stack traces, analyzing logs, fixing null references, detecting race conditions, and more. Each prompt is accompanied by a real-world example so you can copy it, adapt it, and start using it immediately.
Why Prompt Engineering Matters for Debugging
AI models are not mind readers. They respond to the information you give them and the constraints you set. For debugging tasks, a good prompt includes four elements:
- Role — 'Act as a senior SRE' sets the context and makes the model use more relevant terminology.
- Context — the exact error message, log, or code snippet.
- Task — what you want the model to produce: a hypothesis, a fix, or a list of edge cases.
- Constraints — format, length, or tone. Telling the model to output a Markdown table makes the result scannable.
This pattern is widely used in the OpenAI Cookbook and by practitioners who've documented their workflows. The more constrained the prompt, the higher the chance of getting a useful answer.
The 10 Prompts
1. The Structured Bug Report
Purpose: Turn a raw error into something your whole team can act on.
Prompt template:
Act as an experienced QA engineer. I will give you an exception and a stack trace. Create a bug report with the following sections: Environment, Steps to reproduce, Expected result, Actual result, Root cause hypothesis, Suggested fix. Keep it concise. Here is the error:
<paste error and stack trace>
Case study: A junior developer in our example tripped over a NullReferenceException in a C# web API. The AI produced a report that identified the method call on a null object and suggested a null check. The team skipped a 30-minute debugging session and went straight to a code review. The key benefit: a clear structure makes the report actionable and reduces back-and-forth.
2. The Root Cause Detective
Purpose: Find the underlying cause of an issue from incomplete or messy logs.
Prompt template:
You are a senior backend engineer. Analyze the following log output and identify the root cause of the failure. Trace the chain: user request -> service call -> database query. List possible causes with a probability estimate, and name the most likely one. Also suggest one diagnostic command to confirm. Log:
<paste log>
Case study: A production log showed a TimeoutException on a database call. The AI pointed out that the connection pool was exhausted because of a missing using statement in C#. The suggested command, SELECT * FROM pg_stat_activity, revealed 50 idle connections. That one hint gave the developer a clear fix instead of blindly increasing the timeout.
3. The Rubber Duck Debugger
Purpose: Use the model as a rubber duck—explain your code to it, and let it spot the logical flaw.
Prompt template:
Pretend you are a thorough code reviewer. Explain what this code does line by line, and point out any logical bugs or edge cases you notice. Do not rewrite the code unless you find a bug. Code:
<paste code>
Case study: A developer had a Python function that calculated discounts on an e-commerce site:
def discount(price, is_member, is_sale):
if is_member or is_sale:
return price * 0.9
return price
The AI's line-by-line explanation showed the or allowed a non-member to get a discount during a sale. The developer changed it to and, and the test suite passed. The prompt is useful because the model explains the intended behavior, making contradictions obvious.
4. The Edge-Case Test Generator
Purpose: Generate a suite of tests that reveal hidden bugs before you fix them.
Prompt template:
Here is a function that has a bug. Before fixing it, generate a comprehensive set of unit tests in {language} using {test framework}. Include edge cases: empty input, zero values, negative numbers, maximum size, and invalid types. For each test, explain what behavior it checks. Function:
<paste function>
Case study: For a simple divide function, the AI generated tests that included division by zero, division by a float, and division by very large numbers. One test caught that the function didn't handle decimal.Decimal, which caused a silent precision loss. The developer fixed the type check and added the test to the repo. In this way, the prompt not only found a bug but also left behind better coverage.
5. The Null Pointer Hunter
Purpose: Find every possible null or undefined reference before it crashes.
Prompt template:
You are a static analyzer. Review this code and find every variable that could be null or undefined at the point of use. Use a data-flow approach: assignment, function return, API response. For each occurrence, output: line number, variable, reason, severity (low/medium/high), and a safe default value or guard clause. Code:
<paste code>
Case study: In a JavaScript mapper function, user.address.city crashed when the address field was optional. The prompt returned a table with seven potential nulls, including one from response.data being an empty object. The developer used optional chaining: user?.address?.city ?? 'N/A', and also handled the empty response. This prompt turns a single crash into a proactive review.
6. The Performance Bottleneck
Purpose: Identify memory or time hot spots and get a refactoring suggestion.
Prompt template:
As a performance engineer, profile the following code for time and space complexity. Point out bottlenecks, especially nested loops, redundant computations, and I/O operations. Suggest a refactored version and estimate the complexity improvement without specific percentages. Code:
<paste code>
Case study: An internal Python script found duplicate email addresses with a nested loop:
duplicates = []
for i in range(len(emails)):
for j in range(i+1, len(emails)):
if emails[i] == emails[j]:
duplicates.append(emails[i])
The AI correctly identified this as O(n^2) and suggested using a set. After refactoring, the script processed 100,000 records in seconds rather than minutes. The prompt forces the model to justify performance changes, so you don't end up with random micro-optimizations.
7. The Exception Explainer
Purpose: Decode cryptic error messages in plain English.
Prompt template:
I encountered this error message in {language}:
`{error message}`
Explain:
1. What this error literally means
2. The most common causes (with examples)
3. How to fix it without breaking existing behavior
Use simple language and a step-by-step list.
Case study: The error SQLite3::SQLException: no such column: user_id was explained as a mismatch between the model and the database schema. The AI suggested comparing the migration file with the model definition. The cause was a missing user_id column in the migration. The fix was a one-line change, but the explanation was valuable because it taught the developer how Rails migrations work internally.
8. The Log Analyzer
Purpose: Find patterns and spikes in large volumes of log lines.
Prompt template:
You are a reliability engineer. I'll give you a log fragment with thousands of lines. Analyze it and answer:
- What is the most frequent error type?
- At what timestamps do errors spike?
- Which request path is most affected?
- Propose one hypothesis for the spike and one metric to monitor.
Log lines are in the format `[timestamp] [level] [service] message`. Log:
<paste log>
Case study: In a sample of an API log, the AI detected that 503 errors spiked at 09:00 and correlated with a restart event. The most affected path was /api/orders. The hypothesis was a memory leak that forced restart. The AI suggested monitoring heap usage and GC pauses. This matched the known issue and helped the team set up an alert before the next restart.
9. The Memory Leak Finder
Purpose: Detect objects that are retained in memory longer than necessary.
Prompt template:
Act as a JVM memory expert. Here is a heap dump summary and code. Identify objects that might be stuck in memory because of static references, unclosed resources, or event listeners. Suggest a fix for each. Summary:
<paste summary>
Case study: A long-running Java service repeatedly ran OutOfMemoryError. The AI noted a static Map used as a cache with no eviction policy. It suggested replacing it with Caffeine and setting a time-based expiration. After the fix, heap usage plateaued instead of climbing. This prompt is particularly useful for services that are restarted too often.
10. The Race Condition Spotter
Purpose: Find concurrency bugs that only appear under load.
Prompt template:
You are a concurrency expert. Review this code for race conditions, deadlocks, or visibility problems. Pay attention to shared variables, locking order, and mutable state. For each issue, provide a sample interleaving that triggers it, and a fix using {language} concurrency primitives. Code:
<paste code>
Case study: In a Python script with two threads incrementing a shared counter, the AI showed how the interpreter's GIL led to lost updates:
counter = 0
def increment():
global counter
for _ in range(100000):
counter += 1
The AI explained that counter += 1 consists of read, add, write, and that without a lock the operations interleave. It suggested using threading.Lock. After applying the fix, the counter behaved correctly under stress.
Common Mistakes When Using AI for Debugging
Even with a good prompt, there are pitfalls:
- Providing no context: A bare exception is like a photo of a car engine from one angle. Include the relevant code, library versions, and environment.
- Accepting the first answer: Use the prompt to get a hypothesis, then verify it with a quick experiment. AI models can hallucinate function names and line numbers.
- Ignoring the output format: If you don't specify a format, you get a wall of text. Ask for a table, a list, or a diff.
Quick Reference Table
| Prompt | Best Time to Use | Key Output |
|---|---|---|
| Structured Bug Report | Right after a crash | Ticket-ready bug report |
| Root Cause Detective | When logs are confusing | Prioritized hypotheses |
| Rubber Duck Debugger | When code behaves unexpectedly | Line-by-line explanation |
| Edge-Case Test Generator | Before fixing a bug | Unit test suite |
| Null Pointer Hunter | When facing a null reference | Risk table with guards |
| Performance Bottleneck | When code runs slowly | Complexity analysis |
| Exception Explainer | When error message is cryptic | Plain-English breakdown |
| Log Analyzer | During an incident | Pattern spike analysis |
| Memory Leak Finder | When memory grows over time | Retention issue list |
| Race Condition Spotter | On intermittent failure | Interleaving and fix |
Sources and Further Reading
- OpenAI Cookbook has a collection of prompting techniques that apply to debugging tasks: https://cookbook.openai.com
- David Agans' book 'Debugging: The 9 Indispensable Rules' remains a classic manual for systematic problem solving. The rules (e.g., 'Read the damn error message') are still relevant.
- The 12-Factor App recommends treating logs as event streams, which makes log analysis with AI much easier: https://12factor.net/logs
Conclusion
These ten prompts cover the most common debugging scenarios you'll encounter in a development cycle. The common denominator is specificity: you give the AI a role, the raw material, and a clear deliverable. Start with the structured bug report prompt on your current ticket; you'll immediately see the difference between asking an AI for help and directing it to a solution.
If you use an AI assistant for debugging on a weekly basis, you'll likely develop your own variations. Share them with your team—and if you have a prompt that works particularly well, feel free to leave it in the comments.
Comments