Communitygithub.com

jaimegago/agent-skills

Mid-Debugging ein Setzen, wenn eine React-Oberfläche Daten nicht korrekt anzeigt, obwohl die Quelle korrekt ist – z.B. eine Komponente rendert nichts oder veraltete Inhalte, obwohl die API die richtige Antwort liefert, ein React-Query-/Data-Fetching-Hook hängt fest oder das Netzwerkpanel zeigt einen erfolgreichen 200-Status an, doch die UI aktualisiert sich nicht. Für die DIAGNOSE dieses Laufzeit-/Timing-Verhaltens durch Live-Status-Inspektion, nicht für den Bau oder das Styling von UI. Nicht für Build-/Kompilierungsfehler, reine Styling-Probleme oder Fälle, in denen die API tatsächlich falsche oder fehlende Daten liefert.

Was ist agent-skills?

Diese Skill-Anleitung hilft Entwicklern, ein häufiges, aber frustrierendes Problem zu diagnostizieren: Eine React-Oberfläche zeigt Daten nicht oder falsch an, obwohl die Netzwerkantwort korrekt ist. Der Fokus liegt auf Laufzeit-/Timing-Fehlern, die durch das Zusammenspiel mehrerer korrekter Komponenten entstehen – nicht auf Fehlern in einzelnen Quelldateien. Die Anleitung erklärt, warum der übliche Reflex, den Quellcode erneut zu lesen, in diesem Fall in die Irre führt, und schlägt stattdessen eine gezielte Live-Inspektion des React-Query-Observers im Browser vor. Sie enthält konkrete Codebeispiele, um den Observer zu finden, seinen Status (z.B. `status`, `fetchStatus`, `dataUpdateCount`) auszulesen und einen manuellen Refetch zu erzwingen. So können Entwickler schnell unterscheiden, ob die Datenpipeline grundsätzlich defekt ist oder ob die initiale Query durch eine Cache-Löschung, eine Invalidierung oder eine Remount-Race-Condition unterbrochen wurde. Die Anleitung ist für React-Query v5 und React 18 optimiert, aber die Methodik ist allgemein übertragbar.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jaimegago/agent-skills/tree/HEAD/frontend-runtime-debugging

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Frontend-Runtime-Debugging: Live-Status inspizieren, bevor Quellcode erneut gelesen wird

Die Daten auf der Leitung sind korrekt, aber die UI ist falsch. Dies ist ein Laufzeit-/Timing-Fehler, und der Instinkt, der Zeit verschwendet, ist das erneute Lesen von Quelldateien. Widerstehe ihm. Ordne den Reflex um.

Wann anwenden

Mid-Debugging aufrufen, wenn das Symptom auftritt – nicht zu Beginn einer Aufgabe. Anwenden, wenn ALLE folgenden Bedingungen erfüllt sind:

  • Eine React-Komponente rendert nichts, veraltete oder leere Inhalte.
  • Die benötigten Daten sind an der Quelle korrekt (die API/der Backend gibt die richtige Antwort zurück).
  • Die Lücke liegt irgendwo zwischen „korrekte Antwort auf der Leitung“ und „korrektes Rendern auf dem Bildschirm“.

Typische Formulierungen: „die API gibt die richtigen Daten zurück, aber die Komponente ist leer“, „react-query hängt fest“, „die Anfrage ist 200, aber die UI aktualisiert sich nie“, „es funktioniert nach einem Refresh, aber nicht beim ersten Laden“.

Wofür dies NICHT geeignet ist

  • Build-/Kompilierungsfehler – das ist ein Toolchain-Fehler, kein Laufzeitfehler.
  • Reine Styling-/Layout-Probleme – die Daten werden gerendert, sie sehen nur falsch aus.
  • Die API gibt tatsächlich falsche oder keine Daten zurück – das ist ein normaler Backend-/Vertragsfehler. Überprüfe zuerst die Response auf der Leitung; wenn die Antwort tatsächlich falsch oder leer ist, stoppe und behebe den Backend-/Vertragsfehler. Diese Skill ist nur für den Fall, dass die Leitung korrekt ist, aber die UI nicht.

Die Umordnung (die tragende Lektion)

  1. Live-Runtime-Status INSPIZIEREN, BEVOR Quellcode erneut gelesen wird. Der Reflex ist, die Komponente, das Schema, das Layout und die Provider-Verdrahtung erneut zu lesen, um den Fehler zu jagen. Wenn die Daten auf der Leitung korrekt sind, aber die UI nicht, ist dieser Reflex eine Falle: Der Fehler liegt häufig NICHT in einer einzelnen Quelldatei, sondern in einer Laufzeit-/Timing-Interaktion zwischen Teilen, die jeweils einzeln korrekt sind. Die Code-Review ist strukturell blind für diese Klasse. Sieh dir zuerst den Live-Status an.

  2. Ein 200 im Netzwerkpanel kann aktiv in die Irre führen. Eine Anfrage mit 200 bedeutet, dass die Antwort angekommen ist. Es bedeutet NICHT, dass die Daten die Komponente erreicht oder in den Cache übernommen wurden. Die Antwort kann ankommen und dann verworfen, entfernt oder nie übernommen werden. Ziehe nicht den Schluss „der Fetch funktioniert“ aus einem 200 – bestätige, dass die Daten tatsächlich den Zustand der verbrauchenden Komponente erreicht haben.

  3. Bei React-Query inspiziere den Live-Query-Observer der betroffenen Komponente, nicht nur das Netzwerk. Lies die Werte status, fetchStatus, dataUpdateCount und error des Observers.

    • Ein Query, das bei status: "pending" / fetchStatus: "fetching" mit dataUpdateCount: 0 festhängt, bedeutet, dass das Ergebnis des queryFn-Promises nie im Observer gelandet ist. Das deutet darauf hin, dass die Query während der Ausführung entfernt oder ungültig gemacht wurde – NICHT auf einen fehlgeschlagenen Fetch.
    • Bestätige, dass der queryFn selbst gesund ist, indem du einen manuellen Refetch auf dem Observer erzwingst. Wenn ein manueller Refetch sofort und korrekt auflöst, sind Fetch/Client/Schema alle in Ordnung, und der eigentliche Fehler ist, dass die ursprüngliche Query gestrandet wurde (entfernt durch eine Cache-Bereinigung, ungültig gemacht durch einen Effekt oder abgerissen durch ein Remount). Diese einzelne Beobachtung unterscheidet „der Datenpfad ist kaputt“ von „der Datenpfad ist in Ordnung, aber die Query wurde getötet“ – völlig unterschiedliche Fehler.
  4. Wenn der Fehler auf „gestrandete Query während des Flugs“ eingegrenzt wurde, suche upstream im Lifecycle-/Cache-Management. Die Ursache ist etwas, das im selben Moment wie der Query-Start ausgeführt wurde: ein removeQueries / invalidateQueries / Cache-Reset oder ein Mount/Unmount/Remount-Race. Sieh dir Auth-/Session-Transition-Effekte, Principal-/Tenant-Switch-Bereinigungen und Provider-Remounts an – NICHT den Fetch-Code.

Entscheidungspfad

UI falsch, Daten an der Quelle korrekt?
  → bestätige, dass die Netzwerkantwort tatsächlich korrekt ist (nicht Aufgabe dieser Skill, wenn nicht)
  → lese den Live-Query-Observer der betroffenen Komponente
       status pending + fetchStatus fetching + dataUpdateCount 0?
          → erzwinge einen Refetch auf diesem Observer
               refetch löst sofort & korrekt auf?
                  → queryFn ist IN ORDNUNG. Fehler = initiale Query gestrandet.
                    Jage upstream: removeQueries/invalidateQueries/reset,
                    Remount/Unmount-Race, Auth-/Session-/Tenant-Purge-Effekt.
               refetch schlägt auch fehl?
                  → Datenpfad wirklich kaputt. Inspiziere queryFn/Client/Schema.
       hat Daten, aber UI immer noch leer?
          → Render-/Selector-/Conditional-Fehler in der Komponente, jetzt Quellcode erneut lesen.

Live-Inspektionswerkzeuge (Anhaltspunkte, keine stabilen APIs)

Diese erreichen den React-Query-Observer einer Komponente auf einer laufenden Seite, indem sie den React-Fiber-Baum von einem gerenderten DOM-Element aus durchlaufen, den aktuellen Query-Zustand des Observers auslesen und einen Refetch erzwingen, um zu beweisen, dass der queryFn funktioniert.

Diese Code-Snippets sind versionsabhängig. Sie wurden gegen @tanstack/react-query v5.90 und React 18 Fiber-Interna abgeleitet, stützen sich auf undokumentierte Interna und werden DRIFTEN. Behandle sie als Ausgangspunkte zur Anpassung – überprüfe die Feldnamen und die Fiber-Struktur anhand der im Projekt installierten Versionen, bevor du einem Ergebnis vertraust. Sie sind Anhaltspunkte, keine garantiert stabilen APIs.

Durchlaufe den Fiber-Baum von einem DOM-Knoten aus, um Hooks/Observer zu finden:

// Wähle ein DOM-Element, das von der betroffenen Komponente gerendert wird (z.B. via $0 in den Devtools).
const el = $0; // oder document.querySelector('[data-testid="..."]')
const key = Object.keys(el).find(k => k.startsWith('__reactFiber$'));
let fiber = el[key];

// Durchlaufe den Fiber-Baum auf/abwärts; memoizedState ist eine verkettete Liste von Hooks.
// React-Query speichert seinen Observer auf dem memoizedState eines Hooks.
function* fibers(root) {
  const stack = [root];
  while (stack.length) {
    const f = stack.pop();
    if (!f) continue;
    yield f;
    if (f.child) stack.push(f.child);
    if (f.sibling) stack.push(f.sibling);
  }
}

// Durchsuche den Hook-Status nach etwas, das wie ein QueryObserver aussieht.
function findObservers(fiber) {
  const found = [];
  for (const f of fibers(fiber)) {
    let hook = f.memoizedState;
    while (hook) {
      const s = hook.memoizedState;
      if (s && typeof s === 'object') {
        // QueryObserver-Instanzen exponieren getCurrentResult()/getCurrentQuery().
        if (typeof s.getCurrentResult === 'function') found.push(s);
        // Einige Versionen verschachteln es; überprüfe auch gängige Wrapper.
        if (s.observer && typeof s.observer.getCurrentResult === 'function') found.push(s.observer);
      }
      hook = hook.next;
    }
  }
  return found;
}

const observers = findObservers(fiber);

Lese den Live-Query-Zustand eines Observers:

const obs = observers[0];
const r = obs.getCurrentResult();
console.log({
  status: r.status,            // 'pending' | 'error' | 'success'
  fetchStatus: r.fetchStatus,  // 'fetching' | 'paused' | 'idle'
  dataUpdateCount: obs.getCurrentQuery().state.dataUpdateCount,
  error: r.error,
});
// pending + fetching + dataUpdateCount 0  ==>  gestrandet während des Flugs, kein fehlgeschlagener Fetch.

Erzwinge einen Refetch, um zu beweisen, dass der queryFn gesund ist:

obs.refetch().then(r => console.log('refetch:', r.status, r.data)).catch(e => console.log('refetch failed:', e));
// Löst sofort & korrekt auf  ==>  queryFn/Client/Schema sind in Ordnung;
//                                       die ursprüngliche Query wurde upstream getötet.

Wenn das Projekt den QueryClient exponiert (z.B. auf window zum Debuggen oder über eine Provider-Fiber erreichbar), bevorzuge queryClient.getQueryCache().findAll() und inspiziere den state und die observers jeder Query direkt – das ist robuster als Fiber-Durchlauf, wenn verfügbar.

Abschluss

Wenn du den Fehler lokalisiert hast:

  1. Gib an, auf welcher Seite der Gabelung er liegt: „Datenpfad kaputt“ vs. „Query gestrandet“.
  2. Wenn gestrandet, nenne die Upstream-Lifecycle-/Cache-Aktion, die die Query getötet hat.
  3. Erst dann lies die spezifische verantwortliche Quelldatei erneut – jetzt weißt du, welche.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Verwandte Skills