Claude Code Debugging-Workflow: beobachten, reproduzieren, fixen, testen
Praktischer Debugging-Ablauf mit Claude Code, TypeScript, Node, Vitest, Prompts, Tests und CTA-Prüfung.
Claude Code kann aus einer Fehlermeldung einen plausiblen Fix erzeugen. Produktions-Debugging braucht aber mehr als einen plausiblen Patch. Eine zuverlässige Sitzung trennt Beobachtung, Hypothese, minimale Reproduktion, Korrektur und Regressionstest. Sonst verschwindet der Bug an einer Stelle und kommt über anderen Input, Sprache oder Deploy zurück.
Dieser Artikel nutzt TypeScript, Node und Vitest. Kombinieren Sie ihn mit Claude Code and TDD, wenn die Fehlerbedingung bleiben soll, mit error handling patterns, wenn das Exception-Modell unklar ist, und mit build error triage loop, wenn das Beweiskommando vorher scheitert.
Claude Code eine Untersuchungsreihenfolge geben
Eine vage Bitte wie “fix diesen Fehler” führt zum ersten plausiblen Patch. Besser sind vollständiger Fehler, Stack Trace, Reproduktion, Eingabeform, Erwartung, Ist-Verhalten und zuletzt geänderte Dateien. Fordern Sie drei Hypothesen vor der Änderung.
Beobachtung sammelt Fakten. Hypothese erklärt mögliche Ursachen. Minimale Reproduktion macht daraus einen fehlschlagenden Test oder ein Script. Der Fix bleibt klein, und der Regressionstest bleibt im Repository.
{
"name": "claude-debug-lab",
"private": true,
"type": "module",
"scripts": {
"test": "vitest run",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "^22.0.0",
"typescript": "^5.6.0",
"vitest": "^3.0.0"
}
}
Beispiel 1: undefined map als Regel behandeln
Der erste Bug ist verbreitet: Code ruft map auf Daten auf, die noch nicht da sind. Ziel ist nicht nur Crash-Vermeidung. Die Regel lautet: fehlendes Payload ergibt leere Liste, leere Namen fallen weg, gültige Namen werden getrimmt.
export type User = {
id: string;
name?: string | null;
};
export function normalizeUsers(users: User[] | null | undefined): string[] {
if (!Array.isArray(users)) return [];
return users
.filter((user): user is User & { name: string } => typeof user.name === "string")
.map((user) => user.name.trim())
.filter((name) => name.length > 0);
}
import { describe, expect, it } from "vitest";
import { normalizeUsers } from "../src/normalize-users.js";
describe("normalizeUsers", () => {
it("returns an empty list when the API payload is missing", () => {
expect(normalizeUsers(undefined)).toEqual([]);
expect(normalizeUsers(null)).toEqual([]);
});
it("keeps only usable display names", () => {
expect(
normalizeUsers([
{ id: "u1", name: " Masa " },
{ id: "u2", name: "" },
{ id: "u3", name: null },
]),
).toEqual(["Masa"]);
});
});
Nutzen Sie diesen Prompt:
Wir sehen Cannot read properties of undefined (reading 'map').
normalizeUsers muss fehlende API-Payloads tolerieren und leere display names entfernen.
Füge zuerst einen fehlschlagenden Vitest hinzu und mache dann den kleinsten Fix.
Führe am Ende npm test und npm run typecheck aus.
Der Fehler ist, bei users ?? [] aufzuhören. Das verhindert vielleicht den Crash, definiert aber null names, leere Strings und nicht-Array-Payloads nicht. Geben Sie Claude Code die Produktregel, nicht nur die Exception.
Beispiel 2: async retry ohne letzte Fehlermeldung zu verstecken
Async-Retry-Bugs wirken oft sporadisch. Ein guter Test prüft Aufrufzahl, Warten, finalen Erfolg und totalen Fehler. Wird die letzte Fehlermeldung geschluckt, verliert Incident Response den Hinweis auf den fehlerhaften Dienst.
type RetryOptions = {
times: number;
delayMs: number;
sleep?: (ms: number) => Promise<void>;
};
const defaultSleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
export async function retry<T>(
task: () => Promise<T>,
{ times, delayMs, sleep = defaultSleep }: RetryOptions,
): Promise<T> {
let lastError: unknown;
for (let attempt = 1; attempt <= times; attempt += 1) {
try {
return await task();
} catch (error) {
lastError = error;
if (attempt < times) await sleep(delayMs);
}
}
throw lastError instanceof Error ? lastError : new Error("Retry failed");
}
Nennen Sie Mock-Isolation, keinen großen Refactor und Erhalt des letzten Fehlers. Temporäre Logs sind für die Untersuchung okay, gehören aber nicht in den finalen Patch, außer das Produkt braucht bewusst strukturiertes Logging.
Beispiel 3: Datumsgrenzen vor UI-Änderungen reproduzieren
Das dritte Beispiel ist ein Datumsgrenzen-Bug. In der Oberfläche sieht es so aus, als ob der März-Export Bestellungen vom 31. März verliert. Die Ursache liegt aber oft im Vergleich zwischen Monatsbeginn und Beginn des Folgemonats.
export type Order = {
id: string;
createdAt: string;
total: number;
};
export function exportMonthlyOrderIds(orders: Order[], month: string): string[] {
const [yearText, monthText] = month.split("-");
const year = Number(yearText);
const monthIndex = Number(monthText) - 1;
const start = new Date(Date.UTC(year, monthIndex, 1));
const end = new Date(Date.UTC(year, monthIndex + 1, 1));
return orders
.filter((order) => {
const createdAt = new Date(order.createdAt);
return createdAt >= start && createdAt < end;
})
.map((order) => order.id);
}
import { describe, expect, it } from "vitest";
import { exportMonthlyOrderIds } from "../src/export-orders.js";
describe("exportMonthlyOrderIds", () => {
it("includes orders from the first day through the last moment of the month in UTC", () => {
const orders = [
{ id: "feb-end", createdAt: "2026-02-28T23:59:59.999Z", total: 1000 },
{ id: "mar-start", createdAt: "2026-03-01T00:00:00.000Z", total: 2000 },
{ id: "mar-end", createdAt: "2026-03-31T23:59:59.999Z", total: 3000 },
{ id: "apr-start", createdAt: "2026-04-01T00:00:00.000Z", total: 4000 },
];
expect(exportMonthlyOrderIds(orders, "2026-03")).toEqual(["mar-start", "mar-end"]);
});
});
Sage Claude Code, dass lokale Zeitzonen nicht Teil der Lösung sein dürfen. Die Regel lautet: Monatsbeginn einschließen, Beginn des Folgemonats ausschließen.
Kopierbarer Debugging-Prompt
Ziel:
Ursache finden, Regressionstest hinzufügen und mit kleinstem sinnvollen Diff fixen.
Beobachtungen:
- Vollständiger Fehler:
- Reproduktionsschritte:
- Erwartetes Verhalten:
- Tatsächliches Verhalten:
- Kürzlich geänderte Dateien:
Regeln:
- Drei Hypothesen vor dem Editieren nennen.
- Keine großen Refactors.
- Typfehler nicht mit any verstecken.
- Temporäre Logs am Ende entfernen.
- Am Ende npm test und npm run typecheck ausführen.
Bericht:
- Ursache
- Geänderte Dateien
- Hinzugefügter Regressionstest
- Restrisiken
So wird Claude Code zum Untersuchungspartner. Reviewer sehen Ursache, Beleg und Risiko vor dem gesamten Diff. Im Team gehören dieselben Felder in den review gate, damit KI- und Menschen-Diffs denselben Standard haben.
Debugging ohne Umsatzpfad zu brechen
Auf öffentlichen Sites muss Debugging auch CTAs prüfen. Ein Content-Fix kann das Gratis-PDF-Formular verschieben, einen Gumroad-Link ändern oder Beratung weniger sichtbar machen. Je populärer der Artikel, desto wichtiger ist revenue routing im Debugging-Umfang.
Eine kleine Regel reicht:
const debuggingRoutes = {
first_error: "free_pdf",
repeated_bugfixes: "prompt_templates",
setup_or_ci_blocked: "setup_guide",
team_process_blocked: "consultation",
};
export function chooseDebuggingCta(intent) {
return debuggingRoutes[intent] ?? "free_pdf";
}
console.log(chooseDebuggingCta("repeated_bugfixes"));
Das free cheatsheet passt zu Einsteigern und Vergleichslesern. 50 Prompt Templates passt zu wiederholtem Debugging und Review. Setup Guide passt zu Permissions, CI/CD und Setup. Beratung passt zu Team-Rollout und Betriebsentscheidungen.
Was geprüft wurde
Diese Neufassung enthält sauberen UTF-8-Text, ausführbare Codeblöcke, interne Links, externe Links sowie Pfad zu Gratis-PDF, Gumroad und Beratung. Nächste Kennzahlen sind PDF-Anmeldungen, Prompt-Templates-Klicks, Setup-Guide-Klicks und Training-Besuche von diesem Slug.
Prüfnote nach Veröffentlichung
Bei einem Debugging-Artikel endet die Arbeit nicht bei korrektem Code. Öffnen Sie die öffentliche URL und prüfen Sie h1, canonical, Textanfang, hero image, Gratis-PDF-Formular, Gumroad-Links und Beratung. In einem populären Artikel kann ein besserer Debugging-Ablauf direkt die nächste Leseraktion beeinflussen. Wenn Erklärung besser ist, aber PDF, Gumroad oder Beratung falsch sind, ist der Umsatzpfad unfertig.
In lokalisierten Versionen dürfen Codebeispiele gleich sein, aber Erklärung und CTA müssen in der Zielsprache stehen. Leser sollen Beobachtung, Reproduktion, Fix und Test ohne Sprachwechsel verstehen. In der Screenshot-Prüfung zählen Textanfang, Prompt-Bereich und CTA-Bereich.
Die nächsten Kennzahlen sind PDF-Anmeldungen, Prompt-Templates-Klicks, Setup-Guide-Klicks und Training-Besuche von diesem Slug. Debugging-Leser haben akuten Schmerz, deshalb zählt Bewegung nach dem Artikel mehr als reine PV.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Workflow von Obsidian zu CLAUDE.md
Obsidian-Arbeitsnotizen in CLAUDE.md-Betriebsnotizen verwandeln und Kontext nicht ständig neu erklären.
Claude Code Revenue CTA Routing: Artikel zu PDF, Gumroad und Beratung führen
Ein Claude-Code-Ablauf, der Leser nach Absicht zu Gratis-PDF, Gumroad oder Beratung führt.
Claude-Code-Team-Handoff-Regeln: Belege, Berechtigungen, Rollback und Umsatzpfade
Ein praktisches Claude-Code-Handoff für Review-Belege, Berechtigungen, Rollback, Gratis-PDF, Gumroad und Beratung.