Skip to content

Instantly share code, notes, and snippets.

@TobyScr
Created February 24, 2026 11:36
Show Gist options
  • Select an option

  • Save TobyScr/505369330b3c8ac1f4416e847ba440d7 to your computer and use it in GitHub Desktop.

Select an option

Save TobyScr/505369330b3c8ac1f4416e847ba440d7 to your computer and use it in GitHub Desktop.
Claude Code skill: structured bug investigation for multi-layer apps (frontend, API, N8N, Xano)
name description argument-hint allowed-tools
diagnose-kora
Structured bug investigation: triage symptoms, identify the failing layer, check the right systems, and present findings to the user before fixing. Invoke with /diagnose-kora [symptom or description].
[symptom e.g. 'system map not loading', 'generation stuck', 'section won't confirm']
Read, Glob, Grep, Bash, Task, AskUserQuestion

Diagnose Skill

You are investigating a bug in the Kora platform. The user's report is: $ARGUMENTS

Your job is to FIND the root cause, not to fix it. Present your findings to the user and let them decide what to do next.


Step 1: Understand the Symptom

If $ARGUMENTS is vague or missing detail, ask the user:

  • What did you see? (error message, blank screen, spinner, wrong data, etc.)
  • What section were you in?
  • What action triggered it? (page load, clicking Generate, confirming, editing)

Do NOT start investigating until you have enough to classify the layer.


Step 2: Classify the Layer

Based on the symptom, identify which layer is most likely failing:

Symptom Most likely layer Start here
UI doesn't render / looks wrong / layout broken Frontend Step 3A
Page loads but shows no data / empty cards Xano data or Frontend fetch Step 3B
"Generate" button does nothing / spins forever API route → N8N Step 3C
Generation completes but data is wrong/missing/malformed N8N output → Xano save Step 3D
Section doesn't unlock after confirming Confirm chain / workflow step Step 3E
Error toast or console error visible Depends on the error Read the error first, then classify

If you're unsure which layer, start with Step 3B (check if data exists in Xano) — this tells you whether the problem is upstream (data was never created) or downstream (data exists but isn't displayed).


Step 3A: Frontend Investigation

The problem is likely in the React component or API route.

  1. Check the browser console — Ask the user if they see any errors in the browser console (or use Playwright to check console.error messages).

  2. Read the component code:

    • Find the section component: Glob for app/src/components/<SectionName>/**/*.tsx
    • Check the page that renders it: app/src/app/intervention/[id]/brief/page.tsx
    • Look for: conditional rendering gates, state management, fetch calls
  3. Check the API route:

    • Find it: Glob for app/src/app/api/interventions/[id]/<section>/**/*.ts
    • Look for: URL construction, error handling, response parsing
  4. Check for TypeScript errors:

    cd /Users/tobyscregg/Documents/Projects/kora-main/app && npx tsc --noEmit 2>&1 | head -50
  5. Check if .next cache is stale — If the user's browser shows different behaviour from what code suggests, try:

    rm -rf /Users/tobyscregg/Documents/Projects/kora-main/app/.next

    Then ask the user to restart the dev server and hard-refresh.

Present findings to the user before proceeding.


Step 3B: Data Investigation (Xano)

Check whether the expected data exists in Xano.

Using the Metadata API (READ-ONLY debugging)

The Metadata API is allowed for debugging — reading data to understand what's in the database. It must NEVER be used in application code, API routes, or for writing data.

# Get the Xano meta token
source /Users/tobyscregg/Documents/Projects/kora-main/app/.env.local

# Check data in a table for a specific intervention
curl -s "https://xyot-fwcy-i2yo.e2.xano.io/api:meta/workspace/41/table/{TABLE_ID}/content" \
  -H "Authorization: Bearer $XANO_META_TOKEN" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
items = data.get('items', [])
# Filter by intervention_id
filtered = [i for i in items if i.get('intervention_id') == INTERVENTION_ID]
print(json.dumps(filtered, indent=2, ensure_ascii=False)[:3000])
"

Table ID Reference

Section Table Table ID
Brief BRIEF_OUTPUT 294
Research RESEARCH_INSIGHTS 337
System Map SYSTEM_MAP 338
Behavioural Objective BEHAVIOURAL_OBJECTIVE_NEW 340
Assumptions ASSUMPTION 341
Research Questions RESEARCH_QUESTION 342
COM-B COM_B 347
Personas PERSONA 348
Generation Log GENERATION_LOG 362

For Design stage table IDs, check docs/xano/xano_endpoints_quick_reference.md.

What to look for:

  • No data at all → Generation never ran or failed silently → go to Step 3C
  • Data exists but looks wrong → N8N produced bad output → go to Step 3D
  • Data exists and looks correct → Frontend isn't fetching/displaying it → go to Step 3A
  • is_confirmed is true but section still shows as unconfirmed → go to Step 3E

Present findings to the user before proceeding.


Step 3C: N8N / Generation Investigation

The "Generate" action isn't working. Trace the full path:

1. Check which API route the frontend calls

Grep for the section's generate endpoint in app/src/

The pattern is: Frontend → POST /api/interventions/[id]/<section>/generate → N8N webhook.

2. Check if N8N received the request

source /Users/tobyscregg/Documents/Projects/kora-main/app/.env.local

# List recent N8N executions
curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
  "https://n8n-toby.sliplane.app/api/v1/executions?limit=10" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
for ex in data['data']:
    print(f'ID: {ex[\"id\"]} | Status: {ex[\"status\"]} | Workflow: {ex[\"workflowId\"]} | Started: {ex[\"startedAt\"]}')
"

3. If there's a failed execution, get the trace

curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" \
  "https://n8n-toby.sliplane.app/api/v1/executions/<EXECUTION_ID>?includeData=true" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
err = data.get('data',{}).get('resultData',{}).get('error',{})
if err:
    print(f'Node: {err.get(\"node\",{}).get(\"name\",\"?\")}')
    print(f'HTTP: {err.get(\"httpCode\",\"?\")}')
    print(f'Message: {err.get(\"description\",\"\") or err.get(\"message\",\"?\")}')
else:
    print('No top-level error — check individual node outputs')
"

4. If no execution exists at all

The request never reached N8N. Check:

  • Is the N8N workflow activated? (webhook-triggered workflows must be active)
  • Is the Next.js API route calling the correct webhook URL?
  • Is the N8N instance running? (try curl -s https://n8n-toby.sliplane.app/healthz)

Common N8N errors

Error Cause Where to fix
500 - Invalid data source X-Data-Source header sent to Xano N8N HTTP Request node — toggle Send Headers OFF
404 - Resource not found Wrong Xano URL or missing intervention_id N8N HTTP Request node — check URL template
Credential does not exist Wrong credential type or ID N8N node — relink credential
Execution "running" forever LLM timeout or infinite loop Check N8N execution data for the stuck node

Present findings to the user before proceeding.


Step 3D: Data Quality Investigation

Generation ran but the output is wrong.

  1. Get the N8N execution trace (see Step 3C.3) and look at the AI Agent node's output — what did the LLM actually return?

  2. Check the Langfuse prompt — Is the prompt producing the expected output format?

    • Prompt catalog: docs/ai/langfuse_prompt_catalog.md
    • Check prompt name and whether latest label is on the right version
  3. Check the save-to-Xano node — Did N8N correctly POST/PATCH the data?

    • Look at the HTTP Request node's input (what was sent) vs the Xano response
  4. Check the transform layer — Is the frontend correctly parsing Xano's response?

    • Read: app/src/lib/transforms/<section>*.ts
    • Xano addon joins flatten data (fields merge into parent, NOT nested under _TableName)

Present findings to the user before proceeding.


Step 3E: Confirm Chain Investigation

A section was confirmed but the next section didn't unlock.

  1. Check the intervention's current_step in Xano:
source /Users/tobyscregg/Documents/Projects/kora-main/app/.env.local

curl -s "https://xyot-fwcy-i2yo.e2.xano.io/api:meta/workspace/41/table/293/content" \
  -H "Authorization: Bearer $XANO_META_TOKEN" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
for item in data.get('items', []):
    if item.get('id') == INTERVENTION_ID:
        print(f'current_step: {item.get(\"current_step\")}')
        break
"
  1. Check the workflow step reference for what the step should advance to:

    • Read docs/workflow_step_reference.md
    • Look up the current section's WORKFLOW_STEP ID and its confirms_to target
  2. Common confirm chain issues:

    • current_step didn't advance → the confirm API route didn't call advanceWorkflowStep
    • current_step is correct but UI doesn't show the next section → frontend gate logic is wrong (check page.tsx conditional rendering)
    • onLoadConfirmed downgraded "complete" back to "in-progress" → missing guard in the section component (check for if (sectionState === "complete") return;)
    • Multi-step confirms (e.g. Personas: 7→8→9→10) → intermediate steps may not have fired

Present findings to the user before proceeding.


Step 4: Present Findings

After investigation, tell the user:

  1. Which layer failed (Frontend / API route / N8N / Xano / Confirm chain)
  2. What specifically is wrong (the error, the missing data, the broken logic)
  3. Root cause if you can identify it
  4. Suggested fix — but do NOT implement it. Ask the user: "Want me to fix this?"

Rules

  • DO NOT fix anything until the user approves. This skill is for diagnosis only.
  • DO NOT use the Metadata API for writes. Read-only for debugging.
  • DO NOT use Playwright unless the user specifically asks you to reproduce the bug visually. Start with code reading and API checks — they're faster and more reliable.
  • Involve the user early. If Step 2 classification is ambiguous, ask before diving deep.
  • Check the simplest explanation first. Is the dev server running? Is the .next cache stale? Is the workflow activated? Don't jump to complex root causes before ruling out the obvious.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment