Przejdź do głównej zawartości

Debugowanie z poziomu CLI

Debugowanie w Claude Code przebiega według stałej sekwencji: wrzuć błąd z pełnym kontekstem, pozwól Claude prześledzić ścieżkę wykonania przez wszystkie pliki ze stack trace’a, zweryfikuj przyczynę źródłową przed jakąkolwiek poprawką, a potem napraw i zabezpiecz zachowanie testem regresyjnym. Bisekcja gita i analiza logów obsługują regresje i awarie występujące tylko na produkcji.

Druga w nocy, CI świeci na czerwono. Komunikat brzmi “Cannot read properties of undefined (reading ‘map’)”, stack trace dotyka sześciu plików w dwóch serwisach, a kolega twierdzi, że wczoraj działało. Git blame wskazuje merge commit z czterdziestoma zmienionymi plikami. Możesz spędzić dwie kolejne godziny na dokładaniu console.log.

Albo przepuścić błąd do Claude Code i mieć przyczynę źródłową w pięć minut. Deweloperzy, którzy debugują najszybciej, nie wklejają samego błędu z prośbą o poprawkę — trzymają się przepływu: podaj Claude błąd z pełnym kontekstem, pozwól mu prześledzić ścieżkę wykonania, zweryfikuj diagnozę przed wprowadzeniem czegokolwiek i napisz test, który zablokuje regresję.

  • Powtarzalną drogę od komunikatu błędu do przyczyny źródłowej w kilka minut, dla dowolnego błędu
  • Prompty dające Claude dość kontekstu, żeby diagnozował prawdziwe błędy, a nie zgadywał
  • Technikę “wrzuć rurą i diagnozuj” dla wyjścia serwera deweloperskiego, produkcji i CI
  • Gotowe schematy dla stack trace’ów, błędów typów, wyścigów, wycieków pamięci i awarii występujących tylko w CI
  • Strategie bisekcji do znalezienia commita, który wprowadził regresję
  • Wzorce trybu headless do automatycznego triage’u błędów w CI
  1. Daj Claude pełny kontekst błędu

    Jakość diagnozy zależy w całości od jakości wejścia. Goły komunikat błędu daje zgadywankę. Stack trace z kontekstem daje przyczynę źródłową. Najszybsze wejście to potok:

    Okno terminala
    cat error.log | claude -p "Analyze this error. What is the root cause and which file should I look at first?"

    Potem kontynuuj interaktywnie w tej samej sesji przez claude -c, który trzyma kontekst błędu załadowany. Jeśli masz do zaoferowania coś więcej niż log, poświęć trzydzieści sekund na uporządkowane zgłoszenie:

  2. Odtwórz awarię

    Jeden błąd, którego upadek widziałeś, jest wart dziesięciu, o których tylko czytałeś:

    Run the failing test: npx jest src/payments/__tests__/process.test.ts
    Show me the exact line where it fails and the state of all variables at that point.
  3. Pozwól Claude prześledzić ścieżkę wykonania

    Claude czyta pliki ze stack trace’a, idzie za importami, sprawdza typy i składa obraz tego, co poszło nie tak. Nie poganiaj tego kroku — to w śledzeniu znajduje się błąd.

    Trace the request flow from src/routes/orders.ts line 47
    through the service layer and into the database query.
    Show me the data shape at each step. Where does the value
    become undefined?
  4. Zweryfikuj diagnozę przed wprowadzeniem poprawki

    Claude potrafi wskazać złą przyczynę źródłową, zwłaszcza przy błędach występujących sporadycznie. Zanim napisze jakąkolwiek poprawkę, każ mu udowodnić tezę:

    You're saying the bug is in the middleware that parses the
    JWT token. Prove it: show me the specific line where the
    undefined value originates, and explain why it only happens
    for users with expired sessions.

    Rozszerzone myślenie jest w Claude Code domyślnie włączone, więc żadne magiczne słowo kluczowe go nie potrzebuje. Przy najtrudniejszych wyścigach najpierw podnieś głębokość rozumowania: wybierz wyższy poziom wysiłku w /model albo ustaw CLAUDE_CODE_EFFORT_LEVEL=high przed uruchomieniem.

  5. Napraw błąd i napisz test regresyjny

    Fix the bug. Then write a test that reproduces the exact
    scenario that caused it -- expired session token with a
    valid user ID. The test should fail without the fix and
    pass with it. Then run the full test suite and show me any
    new failures.
  6. Sprawdź, czy ten sam błąd nie siedzi gdzie indziej

    Search the codebase for other places that use the same
    pattern that caused this bug. Are there other middleware
    functions that assume the token payload is always present?
    List them so I can fix them proactively.

Claude Code jest z natury narzędziem terminalowym, więc wyjście z błędem wchodzi do niego wprost. To najkrótsza droga od awarii do diagnozy i działa wszędzie tam, gdzie błąd i tak się wypisuje.

Okno terminala
# Pipe a failing test directly to Claude
npm test -- --run tests/services/order.test.ts 2>&1 | \
claude -p "This test is failing. Read the test file and the \
source code it tests. Diagnose the root cause and fix it."

Filtruj przed wrzuceniem. Sto istotnych linii bije sto tysięcy surowych, a to właśnie filtrowanie pozwala Claude grupować po przyczynie, zamiast parafrazować twój log:

Okno terminala
# Grab recent errors and analyze them
grep "ERROR" /var/log/app/production.log | tail -50 | \
claude -p "Analyze these production errors. Group them by \
root cause. For each group, identify the source file and \
suggest a fix. Prioritize by frequency."

Kiedy gonisz konkretny incydent, zawęź pytanie do niego:

Okno terminala
# Pipe filtered logs to Claude Code
grep "ERROR\|WARN" /var/log/app.log | tail -100 | \
claude -p "Categorize these errors. Which are most frequent? Which are likely related to the payment processing bug we are investigating?"
Okno terminala
# Pipe CI failure output to Claude
gh run view 12345 --log-failed | \
claude -p "This CI run failed. Identify which test failed, \
read the relevant source code, and explain what broke. \
Check recent commits to see if a specific change caused it."

Ogólnikowa wersja tego promptu dostaje ogólnikową odpowiedź. Ta, która działa, zakazuje ogólnikowych poprawek wprost i kończy się przechodzącym testem:

Gdy zależy ci na samym łańcuchu wywołań, a nie na poprawce, poproś o łańcuch:

Here is a stack trace from production:
[paste stack trace]
1. Identify the root cause (not just the symptom)
2. Trace the call chain from the error back to the original trigger
3. Read the source files involved and explain what went wrong
4. Suggest a fix that addresses the root cause, not just the symptom
This TypeScript error makes no sense to me:
[paste TypeScript error]
Read the file and its imports. Trace the type through every transformation
to find where the type mismatch actually originates. It might not be in the
file the error points to.

Wyścigi trudno debugować, bo zależą od czasu, a mglisty prompt daje mglistą teorię. Nazwij awarię precyzyjnie, a potem podaj Claude listę rzeczy, które faktycznie je wywołują:

We have an intermittent test failure in tests/services/payment.test.ts.
It passes 9 out of 10 times. The error is "expected 'processing'
but received 'completed'".
Read the test and the payment service. Look for any async operations
that might resolve in a different order depending on timing. Identify:
1. Any shared mutable state
2. Any missing await calls
3. Any operations that assume sequential execution
4. Any cleanup that runs before async operations complete
Our Node.js service memory grows from 200MB to 1.2GB over 6 hours,
then crashes with OOM. I took heap snapshots at startup and at
the 4-hour mark.
Read our event handler code in src/handlers/ and look for:
1. Event listeners that are added but never removed
2. Arrays or maps that grow without bounds
3. Closures that capture large objects
4. Streams that are opened but never closed
This test passes on my machine but fails in CI. Here's the CI output:
[paste output]
Here's my local Node version: v20.11.0
CI uses: v20.10.0
Read the test file and look for:
1. Environment-dependent code (paths, timezones, locale)
2. Timing-sensitive assertions
3. Missing test fixtures or setup steps
4. Order-dependent tests that assume state from a previous test

Opóźnienia, które pojawiły się razem z wdrożeniem

Dział zatytułowany „Opóźnienia, które pojawiły się razem z wdrożeniem”
Our API response times increased from 50ms to 800ms after the last deploy.
Run these diagnostics:
1. Check git diff HEAD~1 for changes to database queries
2. Look for any new N+1 query patterns in the changed files
3. Check if any new middleware was added to the request pipeline
4. Look for blocking I/O operations that could explain the latency
Focus on database query changes first -- that is the most common cause.

Claude Code zna gita, co zamienia “we wtorek działało” z bezradnego wzruszenia ramion w przestrzeń przeszukiwania. Zacznij szeroko:

This bug started appearing after last Tuesday's deploy. Run:
git log --oneline --after="2026-02-03" -- src/services/
Then read the diffs for each commit that touched the services
directory. Which commit introduced the change that could cause
"TypeError: Cannot read property 'id' of null" in the order
processing flow?

Kiedy masz commit o znanym dobrym stanie i test odtwarzający błąd, zawęź to wyszukiwaniem binarnym:

The /api/search endpoint was working correctly in commit abc123 (2 weeks ago)
but is broken in HEAD. Help me bisect:
1. Run: git log --oneline abc123..HEAD -- src/api/search/
2. Identify the most likely commit to have introduced the regression
3. Check out that commit and run the relevant test
4. If the test passes, the bug is in a later commit. If it fails, it is in this commit or earlier.
5. Narrow down to the exact commit using binary search.

Jeszcze lepiej: niech git szuka, a Claude czyta:

Kiedy błąd rozciąga się na kilka części systemu, użyj subagentów do równoległego śledztwa, żeby nie zapychać głównego kontekstu nieistotnym kodem.

Use sub-agents to investigate this bug from multiple angles:
1. Trace the request from the API gateway through the auth
middleware to the order service. Find where the user object
loses its organization_id field.
2. Check the database migration history for the organizations
table. Was a column recently renamed or made nullable?
3. Search for all places in the codebase that read
user.organization_id and check if any of them handle
the undefined case.
Report findings so we can pinpoint the root cause.

Każdy subagent działa we własnym kontekście, czyta tyle plików, ile trzeba, i wraca ze zwięzłym podsumowaniem. Twoja główna sesja zostaje czysta na właściwą poprawkę.

Zespołom, które chcą triage’u błędów bez człowieka w pętli, tryb headless zamienia Claude Code w pipeline debugujący z ustrukturyzowanym wyjściem.

Okno terminala
# Automated error analysis in CI
claude -p "Analyze the test failures in this output and
categorize them:
1. Flaky tests (timing-dependent, order-dependent)
2. Real bugs (code logic errors)
3. Environment issues (missing config, wrong versions)
For real bugs, identify the root cause file and line number.
For flaky tests, suggest how to make them deterministic.
$(cat test-output.log)" \
--output-format json > debug-report.json

Ten raport JSON twoje CI wystawia jako komentarz do PR-a albo wysyła na Slacka. Kiedy pipeline ma nie tylko klasyfikować, ale też spróbować naprawy, podaj mu wyjście testów wprost w prompcie:

Claude naprawia objaw, a nie przyczynę. Tak się dzieje, gdy wklejasz sam komunikat błędu bez kontekstu. Zawsze dodaj stack trace, moment wystąpienia, to co zmieniło się ostatnio, i częstotliwość. Zamiast “napraw błąd null pointera” powiedz “obiekt użytkownika jest nullem, bo asynchroniczny fetch ściga się z renderem — napraw wyścig, nie sprawdzenie na null”.

Poprawka psuje coś innego. Claude naprawił błąd, ale nie sprawdził skutków ubocznych. Po każdej poprawce uruchamiaj cały zestaw testów, nie tylko ten od tego błędu. Wpisz to do promptu: “After fixing the bug, run the full test suite and show me any new failures.”

Claude nie potrafi odtworzyć błędu. Najpierw napisz test, który upada: “Before debugging, write a test that reproduces this exact scenario. Run it to confirm it fails.” Upadający test to najmniej dwuznaczne zgłoszenie błędu, jakie istnieje. Przy błędach ujawniających się tylko na produkcji dołóż logi produkcyjne, szczegóły środowiska i dane, które problem wyzwalają — --append-system-prompt to dobre miejsce na taki stały kontekst.

Błąd jest subtelny, a odpowiedzi płytkie. Przy błędach rozciągniętych na wiele plików albo zależnych od czasu zostaw poziom wysiłku na domyślnym, wysokim ustawieniu i obniżaj go tylko wtedy, gdy chcesz szybszych, płytszych odpowiedzi. Zmienisz go w wyborze /model albo przez CLAUDE_CODE_EFFORT_LEVEL. Przy wysokim wysiłku Claude rozważa problem staranniej, zanim cokolwiek zaproponuje.

Bisekcja kłamie na niestabilnym teście. Jeśli test jest sporadyczny, git bisect run oznaczy commity błędnie i z pełnym przekonaniem. Uruchamiaj test kilka razy w każdym punkcie: git bisect run bash -c 'for i in 1 2 3; do npx jest test.ts || exit 1; done'.

Kontekst zapełnia się w długiej sesji. Debugowanie szybko zbiera odczyty plików i wyjście testów. Uruchom /compact Keep all error traces, test output, and diagnostic results, żeby zachować to, co istotne, a resztę zwolnić. Jeśli diagnoza jest już jasna, taniej wyjdzie świeża sesja z samą diagnozą, w której Claude wdroży poprawkę od zera.

Błąd jest naprawiony, test regresyjny stoi. Następny krok to wzmocnienie reszty zestawu testów, żeby kolejny błąd złapać przed wdrożeniem.