Prompt file imported from dork-labs/dorkos (
.claude/commands/debug/api.md). Fill in{{arguments}}before use. Copyright stays with the author.
API & Data Flow Debugging
Debug data-related issues by systematically tracing through the project's data flow layers. This command helps with API failures, data mismatches, stale cache, and service errors.
For anything on the messaging path — a room, a session turn, a task run, a chat integration — read
contributing/observability.mdand start fromdispatchId. Onedsp_<ULID>joins every hop of one message's life, sojq -c 'select(.dispatchId=="dsp_…")'gives you the whole chain in order rather than a layer at a time. If the server is still up,dorkos debug session <id>answers what is only in memory: the lifecycle, the write lock, and what the turn is parked on.
Project Data Flow Architecture
+-------------------+
| React Component | <- UI displays data (FSD layers)
+-------------------+
| TanStack Query | <- Client-side caching & fetching
+-------------------+
| Transport Layer | <- HttpTransport (HTTP and durable streams)
+-------------------+
| Express Route | <- HTTP endpoints (Zod validation, boundary checks)
+-------------------+
| Service Layer | <- Business logic (agent-manager, binding-router, etc.)
+-------------------+
| Data Store | <- SQLite (dork.db) + JSONL transcripts + JSON state files
+-------------------+
Key Differences from Typical Projects
- SQLite, not PostgreSQL — Drizzle ORM (
packages/db) over SQLite (WAL mode), plus JSON state files - No server actions — All mutations go through Express REST endpoints
- Transport abstraction — Client uses
Transportinterface, not direct fetch - SDK transcripts — Sessions are derived from JSONL files on disk, not a database
- Feature-flag guarded — Relay/Mesh/Pulse endpoints return 503 when disabled
Arguments
Parse {{arguments}}:
- If
--url <url>flag provided, navigate to that URL - Remaining text describes the endpoint or feature with issues
- If empty, prompt for details
Phase 1: Issue Identification
Infer the issue type (wrong data / not loading / stale / API error / subsystem-specific) and the likely layer from {{arguments}} and the initial evidence. Ask a clarifying question only if the description is too vague to start tracing.
Phase 2: Initial Assessment
2.1 Check Browser State (if URL provided)
mcp__plugin_playwright_playwright__browser_navigate: { url: "[provided-url]" }
mcp__plugin_playwright_playwright__browser_snapshot: {}
mcp__plugin_playwright_playwright__browser_console_messages: { level: "error" }
mcp__plugin_playwright_playwright__browser_network_requests: { includeStatic: false }
2.2 Check Server Logs
DORK_HOME="apps/server/.temp/.dork"
LOG="$DORK_HOME/logs/dorkos.log"
# Recent errors and warnings (NDJSON format)
tail -200 "$LOG" | python3 -c "
import sys, json
for line in sys.stdin:
try:
obj = json.loads(line)
if obj.get('level', 0) >= 40:
print(f\"[{obj.get('time','')}] {obj.get('msg','')}\"[:200])
except: pass
" | tail -20
2.2b Read the live state, not just the file
The log is the durable record; several answers only exist in process memory and are gone on restart.
dorkos debug dispatches # agents mid-turn, and what ran recently
dorkos debug refusals # what was declined, and whether anyone was told
dorkos debug session <id> # lifecycle, lock holder, pending approvals
dorkos debug projectors # which sessions have a live stream, and who is watching
2.3 Identify the Data Path
Based on the feature, trace the data flow:
- Find the component displaying/mutating the data (FSD layer structure)
- Find the TanStack Query hook in
entities/*/model/orfeatures/*/model/ - Find the Express route in
apps/server/src/routes/ - Find the service in
apps/server/src/services/ - Find the data store (SQLite table, JSONL file, or JSON state file)
Phase 3: Layer Investigation
3.1 Frontend Layer
Read the component file.
Look for:
- How is data being fetched? (useQuery hook from entities/)
- How is data being displayed?
- Are there conditional renders that might hide data?
- Is there error handling?
- Does the Transport context provide the right transport?
3.2 TanStack Query Layer
Read the query hook file in entities/*/model/.
Look for:
- queryKey: Is it unique and correct?
- queryFn: Does it call the right transport method?
- staleTime: Is caching too aggressive?
- enabled: Is the query enabled when it should be?
- select: Is data being transformed correctly?
Common TanStack Query issues:
| Issue | Symptom | Fix |
|---|---|---|
| Stale data | Old data after mutation | Invalidate queries after mutation |
| Cache key collision | Wrong data displayed | Make queryKey more specific |
| Query disabled | No fetch occurs | Check enabled condition |
| Infinite loading | Never resolves | Check queryFn for errors |
| Missing invalidation | Data stale after action | Add queryClient.invalidateQueries() |
3.3 Express Route Layer
Read the route file in apps/server/src/routes/.
Look for:
- Is Zod validation passing? (schema.safeParse)
- Is the boundary check passing? (validateBoundary)
- Is the feature flag enabled? (isRelayEnabled, isMeshEnabled)
- Is the service being called correctly?
- Is the response format correct?
Key route files:
| Route File | Endpoints |
|---|---|
routes/sessions.ts |
Session CRUD, SSE streaming, messages |
routes/relay.ts |
Relay messaging, adapters, bindings |
routes/mesh.ts |
Mesh discovery, agents, topology |
routes/pulse.ts |
Schedules, runs, triggers |
routes/agents.ts |
Agent identity CRUD |
routes/config.ts |
Server configuration |
3.4 Service Layer
Read the service file.
Look for:
- Is data being read/written correctly?
- Are errors being handled and propagated?
- Is the service properly initialized?
- Are dependencies injected correctly?
3.5 Data Store Layer (Ground Truth)
Check actual data in SQLite and state files:
DORK_HOME="apps/server/.temp/.dork"
# SQLite queries for common data
sqlite3 -header -column "$DORK_HOME/dork.db" "SELECT * FROM [table] LIMIT 10;"
# Relay state files
cat "$DORK_HOME/relay/adapters.json" | python3 -m json.tool
cat "$DORK_HOME/relay/bindings.json" | python3 -m json.tool
# Server config
cat "$DORK_HOME/config.json" | python3 -m json.tool
For session data, check SDK transcripts:
# List recent session transcripts
ls -lt ~/.claude/projects/*/ 2>/dev/null | head -10
This establishes ground truth:
- If data exists in DB/files but not in UI -> Issue is in application layers
- If data missing from store -> Issue is in write operation
- If data is wrong in store -> Issue is in mutation logic
Phase 4: Specific Debugging Scenarios
4.1 Data Not Loading
Debugging checklist:
- Check network tab for request (is it being made?)
- Check server logs for errors (NDJSON in
.dork/logs/) - Verify Express route exists and handles the request method
- Check feature flag is enabled (relay, mesh, pulse)
- Verify service returns data
- Check TanStack Query is enabled
4.2 Stale Data After Mutation
Debugging checklist:
- Check mutation endpoint returns success
- Verify TanStack Query invalidation:
queryClient.invalidateQueries() - Check queryKey matches between query and invalidation
- Look for
onSuccesscallbacks that invalidate related queries - Check if data is cached in Zustand store instead of TanStack Query
4.3 Feature Returns 503
This means the feature flag is disabled:
DORK_HOME="apps/server/.temp/.dork"
# Check which features are enabled
cat "$DORK_HOME/config.json" | python3 -c "
import sys, json
cfg = json.load(sys.stdin)
print(f\"Relay: {cfg.get('relay', {}).get('enabled', False)}\")
print(f\"Pulse: {cfg.get('scheduler', {}).get('enabled', False)}\")
print(f\"Mesh: {cfg.get('mesh', {}).get('enabled', False)}\")
"
4.4 API Returns 403
Boundary violation — the requested path is outside the configured boundary:
# Check boundary setting
cat "$DORK_HOME/config.json" | python3 -c "
import sys, json
cfg = json.load(sys.stdin)
print(f\"Boundary: {cfg.get('server', {}).get('boundary', 'default (home dir)')}\")
"
4.5 Session Lock (409)
Another client has the session locked:
# Check server logs for lock information
tail -100 "$DORK_HOME/logs/dorkos.log" | python3 -c "
import sys, json
for line in sys.stdin:
try:
obj = json.loads(line)
if 'lock' in obj.get('msg', '').lower():
print(json.dumps(obj, indent=2))
except: pass
"
Phase 5: Fix Implementation
5.1 Plan the Fix
Track the trace → fix → verify steps with TaskCreate/TaskUpdate when the fix spans multiple layers.
5.2 Verify the Fix
# Check server logs for new errors
tail -20 "$DORK_HOME/logs/dorkos.log" | python3 -c "
import sys, json
for line in sys.stdin:
try:
obj = json.loads(line)
if obj.get('level', 0) >= 40:
print(json.dumps(obj, indent=2))
except: pass
"
If browser URL provided:
mcp__plugin_playwright_playwright__browser_navigate: { url: "[url]" }
mcp__plugin_playwright_playwright__browser_snapshot: {}
mcp__plugin_playwright_playwright__browser_network_requests: { includeStatic: false }
Phase 6: Wrap-Up
## Data Issue Resolved
**Problem**: [Original issue description]
**Layer**: [Where the bug was — Component/Query/Route/Service/Store]
**Root Cause**: [Why the issue occurred]
**Solution**: [What was changed]
**Files Modified**: [List of files]
Quick Reference
Project File Locations
| Layer | Location |
|---|---|
| Components | apps/client/src/layers/features/*/ui/ |
| TanStack Query hooks | apps/client/src/layers/entities/*/model/ |
| Zustand store | apps/client/src/layers/shared/model/app-store.ts |
| Transport interface | packages/shared/src/transport.ts |
| Express routes | apps/server/src/routes/ |
| Services | apps/server/src/services/ |
| Zod schemas | packages/shared/src/schemas.ts, relay-schemas.ts, mesh-schemas.ts |
| SQLite DB | {DORK_HOME}/dork.db |
| Session transcripts | ~/.claude/projects/{slug}/*.jsonl |
| Relay state | {DORK_HOME}/relay/ |
| Server config | {DORK_HOME}/config.json |
| Server logs | {DORK_HOME}/logs/dorkos.log |
Common Express Route Patterns
// Zod validation
const parsed = Schema.safeParse(req.body);
if (!parsed.success)
return res.status(400).json({ error: 'Validation failed', details: parsed.error.format() });
// Boundary check
if (!validateBoundary(req.body.path))
return res.status(403).json({ error: 'Path outside boundary' });
// Feature flag guard
if (!isRelayEnabled()) return res.status(503).json({ error: 'Relay is not enabled' });
TanStack Query Patterns
// Invalidate after mutation
queryClient.invalidateQueries({ queryKey: ['sessions'] });
// Check if query is fetching
const { data, isLoading, error } = useQuery({ queryKey: ['key'], queryFn: fn });
Important Behaviors
- ALWAYS trace through all layers before fixing
- CHECK server logs (NDJSON in
.dork/logs/) for errors - VERIFY data exists in data store (SQLite, JSON files, JSONL)
- ENSURE TanStack Query invalidation after mutations
- CHECK feature flags before investigating subsystem routes
- TEST both success and error states
