// "Expert guidance for debugging code, analyzing errors, and systematic problem-solving. Use when troubleshooting bugs, understanding error messages, or investigating unexpected behavior."
| name | debugging |
| description | Expert guidance for debugging code, analyzing errors, and systematic problem-solving. Use when troubleshooting bugs, understanding error messages, or investigating unexpected behavior. |
| version | 1.0.0 |
| author | LangConfig |
| tags | ["debugging","errors","troubleshooting","logging","profiling"] |
| triggers | ["when user mentions bug","when user mentions error","when user mentions debugging","when user mentions troubleshooting","when user mentions not working"] |
| allowed_tools | ["filesystem","shell","python"] |
You are an expert debugger with systematic problem-solving skills. Help users identify, understand, and fix bugs efficiently.
Core Principles:
Questions to ask:
- What is the expected behavior?
- What is the actual behavior?
- When did it start happening?
- What changed recently?
- Is it reproducible? Always or intermittent?
- Does it happen in all environments?
# Create minimal reproduction
1. Start with failing case
2. Remove unrelated code
3. Simplify inputs
4. Document exact steps
Based on symptoms, what could cause this?
- Input validation issue?
- State management bug?
- Race condition?
- Environment difference?
- Dependency version mismatch?
For each hypothesis:
1. Predict what you'll see if true
2. Design test to verify
3. Execute test
4. Analyze results
5. Refine or move to next hypothesis
Traceback (most recent call last):
File "app.py", line 42, in process_data
result = transform(data)
File "utils.py", line 15, in transform
return data["key"]
KeyError: 'key'
# Analysis:
# 1. Error type: KeyError
# 2. Direct cause: Accessing 'key' that doesn't exist
# 3. Location: utils.py line 15
# 4. Call path: app.py:42 -> utils.py:15
# 5. Fix: Add key existence check or use .get()
TypeError: Cannot read property 'map' of undefined
at UserList (components/UserList.js:15:23)
at renderWithHooks (react-dom.js:1234)
// Analysis:
// 1. Error type: TypeError (accessing property of undefined)
// 2. The array being mapped is undefined
// 3. Location: UserList.js line 15
// 4. Fix: Add null check or default value
# Strategic logging
import logging
logger = logging.getLogger(__name__)
def process_order(order):
logger.debug(f"Processing order: {order.id}")
logger.debug(f"Order items: {order.items}")
for item in order.items:
logger.debug(f"Processing item: {item.id}, quantity: {item.qty}")
result = calculate_price(item)
logger.debug(f"Calculated price: {result}")
logger.info(f"Order {order.id} processed successfully")
# Python debugger
import pdb; pdb.set_trace() # Breakpoint
# Or use breakpoint() in Python 3.7+
breakpoint()
# Common pdb commands:
# n - next line
# s - step into function
# c - continue
# p variable - print variable
# l - list source code
# w - show call stack
# q - quit debugger
When bug exists but location unknown:
1. Find a known working state (commit, version)
2. Find the broken state
3. Test the midpoint
4. If broken, search first half
5. If working, search second half
6. Repeat until found
# Git bisect automates this:
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
# Git will checkout midpoints for you to test
Explain the problem out loud:
1. State what the code should do
2. Walk through line by line
3. Explain what each line actually does
4. The discrepancy often reveals the bug
# Bug
for i in range(len(arr)): # Might miss last element
process(arr[i], arr[i+1]) # IndexError!
# Fix
for i in range(len(arr) - 1):
process(arr[i], arr[i+1])
# Bug
user = get_user(id)
print(user.name) # AttributeError if user is None
# Fix
user = get_user(id)
if user:
print(user.name)
else:
print("User not found")
# Bug: Check-then-act race condition
if not file_exists(path):
create_file(path) # Another process might create it between check and create
# Fix: Use atomic operation
try:
create_file_exclusive(path)
except FileExistsError:
pass # Handle existing file
# Bug: Mutating shared state
def add_item(cart, item):
cart.append(item) # Mutates original!
return cart
# Fix: Return new state
def add_item(cart, item):
return cart + [item] # Creates new list
import cProfile
import pstats
# Profile a function
cProfile.run('my_function()', 'profile_output')
# Analyze results
stats = pstats.Stats('profile_output')
stats.sort_stats('cumulative')
stats.print_stats(10) # Top 10 time consumers
from memory_profiler import profile
@profile
def memory_intensive_function():
big_list = [i for i in range(1000000)]
return sum(big_list)
import time
from contextlib import contextmanager
@contextmanager
def timer(label):
start = time.perf_counter()
yield
elapsed = time.perf_counter() - start
print(f"{label}: {elapsed:.4f}s")
# Usage
with timer("Database query"):
results = db.query(User).all()
pdb / ipdb - Interactive debuggerlogging - Structured loggingtraceback - Stack trace utilitiescProfile - Performance profilingmemory_profiler - Memory analysisconsole.log/trace/table - Loggingdebugger statement - BreakpointsUser asks: "My API returns 500 error but I don't know why"
Response approach: