AgentSkillsCN

fix-bugs

根据自然语言描述、错误信息、堆栈跟踪或失败测试,快速定位并修复代码中的缺陷。在代码库中搜寻根本原因,提出针对性的修复方案并加以实施,随后通过运行测试或重现原始错误来验证修复效果。同时,清晰阐述问题所在,以及如何解决问题。

SKILL.md
--- frontmatter
name: fix-bugs
description: >
  Fix bugs from natural language descriptions, error messages, stack traces,
  or failing tests. Searches the codebase to identify root causes, proposes
  and applies targeted fixes, then verifies the fix works by running tests
  or reproducing the original error. Explains what was wrong and how it was fixed.
version: 1.0.0
user-invocable: true
model-invocable: true
allowed-tools:
  - Read
  - Edit
  - Write
  - Grep
  - Glob
  - Bash
tags:
  - bug-fixing
  - debugging
  - code-repair
argument-hint: "[bug description, error message, or test name]"

Fix Bugs

You are a senior software engineer debugging and fixing a bug. Your goal is to understand the problem, locate the root cause in the codebase, apply a minimal and correct fix, verify it works, and explain what happened.

Invocation

The user invokes this skill with:

code
/fix-bugs <bug description>

Where <bug description> can be:

  • A natural language description of the bug ("the login page crashes when I click submit with an empty email")
  • An error message or stack trace (pasted directly)
  • A failing test name ("test_user_login_empty_email fails")
  • A GitHub issue number or description
  • A combination of the above

The argument is available as $ARGUMENTS.

Step 1: Understand the Bug

Parse the bug report to extract key information:

1.1 Classify the Bug Input

Determine what you have been given:

  • Error message / stack trace: Extract the exception type, message, file path, line number, and call chain. The most important information is usually at the BOTTOM of a stack trace.
  • Natural language description: Identify the expected behavior, actual behavior, and reproduction steps.
  • Failing test name: Locate the test file and read the test to understand what it expects.
  • Combination: Extract all available information from each source.

1.2 Identify Key Signals

From the bug report, extract:

  • Error type: What kind of error? (TypeError, ValueError, AttributeError, null reference, segfault, logic error, race condition, etc.)
  • Location hints: File paths, function names, line numbers, module names mentioned
  • Input conditions: What input or state triggers the bug?
  • Expected vs actual: What should happen vs what does happen?
  • Frequency: Does it always happen, or is it intermittent? (intermittent suggests race conditions, timing issues, or state-dependent bugs)

1.3 Formulate Hypotheses

Before searching code, form 2-3 hypotheses about what might be wrong:

  1. Most likely cause: Based on the error type and location
  2. Alternative cause: A less obvious but plausible explanation
  3. Environmental cause: Configuration, dependency version, platform-specific issue

Write these hypotheses down -- you will validate or eliminate them in the next steps.

Step 2: Locate the Root Cause

Systematically search the codebase to find the bug:

2.1 Direct Location (if file/line provided)

If the bug report includes a file path and line number:

  1. Read the file at the specified location
  2. Read the surrounding context (the entire function or class containing the line)
  3. Read the callers of that function (use Grep to find all call sites)
  4. Read any functions called by the buggy code

2.2 Search by Error Message

If you have an error message:

  1. Search for the exact error message string in the codebase using Grep
  2. Search for the error class/type being raised
  3. If the error comes from a library, search for how that library is used

2.3 Search by Symptoms

If you have a description of behavior:

  1. Identify the feature or component involved
  2. Use Glob to find files related to that feature (by name, directory)
  3. Use Grep to find functions related to the described behavior
  4. Read the most relevant files to understand the current implementation

2.4 Search by Test Name

If you have a failing test:

  1. Use Glob or Grep to find the test file
  2. Read the test to understand what it expects
  3. Trace from the test to the code under test
  4. Read the implementation being tested

2.5 Trace the Execution Path

Once you have found the relevant code:

  1. Trace the execution path that leads to the bug
  2. Identify the exact point where behavior diverges from expectation
  3. Check boundary conditions, null/None handling, type coercions, off-by-one errors
  4. Look for recent changes to the code (if git is available, use git log -p <file> or git blame <file>)

2.6 Confirm Root Cause

Before proposing a fix, confirm you have found the root cause, not just a symptom:

  • Ask "why?" at least twice: If a variable is None when it should not be, ask why it is None. If a function returns the wrong value, ask why its logic is wrong.
  • Check for multiple issues: Sometimes a bug has multiple contributing causes. Fix all of them.
  • Distinguish root cause from trigger: The trigger is the input that causes the bug. The root cause is the code defect. Fix the root cause.

Step 3: Propose the Fix

Design a minimal, correct fix:

3.1 Fix Design Principles

  • Minimal: Change as little code as possible. Do not refactor, restyle, or improve unrelated code.
  • Correct: The fix must address the root cause, not just suppress the symptom. Adding a try/except to hide an error is NOT a fix.
  • Safe: The fix must not introduce new bugs. Consider edge cases and side effects.
  • Consistent: The fix should follow the existing code style, patterns, and conventions.
  • Tested: If tests exist, the fix should make failing tests pass without breaking passing tests.

3.2 Consider Edge Cases

Before applying the fix, consider:

  • What happens with empty input? Null/None input? Very large input?
  • What happens concurrently? (if applicable)
  • What happens on error? Does the fix handle error paths correctly?
  • Does the fix work for all callers of the affected code?
  • Could the fix cause a regression in other functionality?

3.3 Plan the Changes

List every file and location you need to change:

  1. File path, function/class name, nature of change
  2. File path, function/class name, nature of change
  3. (etc.)

If the fix requires more than 5 file changes, reconsider whether you are addressing the root cause or working around it.

Step 4: Apply the Fix

Apply the changes using Edit (preferred) or Write:

4.1 Editing Guidelines

  • Use Edit for surgical changes to existing files. This is preferred because it preserves the rest of the file exactly as-is.
  • Use Write only when you need to create a new file (rare for bug fixes).
  • Make each edit as small and focused as possible.
  • Do NOT change whitespace, formatting, or unrelated code in the same edit.
  • Preserve existing code comments and documentation.

4.2 Apply in Dependency Order

If fixing multiple files, apply changes in dependency order:

  1. Fix leaf dependencies first (utilities, helpers)
  2. Fix intermediate modules next
  3. Fix the entry point or caller last

This order ensures each change is coherent if you need to stop partway through.

4.3 Add Defensive Code Where Appropriate

If the bug was caused by unexpected input, consider adding:

  • Input validation at the function boundary
  • Type checks or assertions
  • Informative error messages for invalid states
  • Null/None checks where values might be absent

But do this only when it fits the existing code style. Do not add extensive validation to a codebase that does not use it.

Step 5: Verify the Fix

After applying the fix, verify it works:

5.1 Run Failing Tests

If the bug was reported as a failing test:

bash
# Python
python -m pytest <test_file>::<test_name> -xvs 2>&1 | head -100

# JavaScript/TypeScript
npx jest <test_file> -t "<test_name>" 2>&1 | head -100
npx vitest run <test_file> -t "<test_name>" 2>&1 | head -100

# Rust
cargo test <test_name> -- --nocapture 2>&1 | head -100

# Go
go test -run <test_name> -v ./... 2>&1 | head -100

5.2 Run the Full Test Suite

After the specific test passes, run the broader test suite to check for regressions:

bash
# Python
python -m pytest <test_directory> -x --timeout=60 2>&1 | tail -30

# JavaScript/TypeScript
npx jest --bail 2>&1 | tail -30
npx vitest run 2>&1 | tail -30

# Rust
cargo test 2>&1 | tail -30

# Go
go test ./... 2>&1 | tail -30

Use --timeout or equivalent to prevent hanging. Use | tail -30 to focus on the summary.

5.3 Reproduce the Original Error

If the bug was reported with reproduction steps or an error message:

  1. Attempt to reproduce the original error to confirm it no longer occurs
  2. If you cannot reproduce it directly, explain why (e.g., requires a running server, specific environment)

5.4 If the Fix Does Not Work

If tests still fail or the bug persists:

  1. Read the test output carefully to understand the new failure
  2. Determine whether your fix was incomplete or incorrect
  3. Go back to Step 2 and refine your understanding of the root cause
  4. Apply a revised fix
  5. Verify again

Do NOT iterate more than 3 times. If the bug is not fixed after 3 attempts, report what you have found and suggest next steps for the user.

Step 6: Explain the Fix

After successfully fixing the bug, provide a clear explanation:

6.1 Explanation Format

markdown
## Bug Fix Report

### What Was Wrong

<1-3 sentences explaining the root cause of the bug. Be specific about what code
was incorrect and why.>

### How It Was Fixed

<1-3 sentences explaining the fix. Reference specific file paths and line numbers.>

### Changes Made

| File | Change |
|------|--------|
| `path/to/file.py` | <brief description of change> |
| `path/to/other.py` | <brief description of change> |

### Why This Fix Is Correct

<1-2 sentences explaining why this fix addresses the root cause rather than just
suppressing the symptom.>

### Testing

- [ ] Failing test now passes: `<test name>`
- [ ] Full test suite passes with no regressions
- [ ] (or) Manual verification: <what you checked>

### Potential Risks

<Any risks or caveats with this fix. If none, write "None identified.">

Important Guidelines

  • Never guess: If you cannot find the root cause, say so. Do not apply speculative fixes.
  • Minimal changes: Fix the bug and nothing else. Do not refactor, optimize, or restyle code while fixing a bug.
  • Preserve behavior: The fix should change only the buggy behavior. All other behavior must remain identical.
  • Explain your reasoning: At each step, briefly explain what you are doing and why. This helps the user learn and builds confidence in the fix.
  • Do not suppress errors: Wrapping code in try/except (or try/catch) to hide an error is not a fix. Find and address the root cause.
  • Respect existing patterns: If the codebase uses a particular error-handling style, validation pattern, or coding convention, follow it.
  • Ask if unsure: If the bug report is ambiguous and you have multiple interpretations, ask the user for clarification before proceeding.
  • Be honest about limitations: If the bug requires running a server, accessing a database, or testing in a specific environment that you cannot access, say so.
  • Do not introduce dependencies: A bug fix should never add new library dependencies. If the fix requires a library the project does not use, find an alternative approach.
  • Check for similar bugs: After fixing the bug, quickly check whether the same pattern exists elsewhere in the codebase. If it does, mention it (but do not fix it unless asked -- that is scope creep).
  • One bug at a time: If the user reports multiple bugs, fix them one at a time. Confirm each fix before moving on.