Files
pi-multifx-pedal/dogfood-output/report.md
T
shawn 77a757cee6 R1: Dashboard 500 fix, Phase 2/7 uncommitted changes
- Fix dashboard 500 when deps disconnected — _gather_state() now returns
  full defaults instead of bare {'connected': False}
- Phase 2: FX param schemas aligned with DSP implementations
- Phase 7: Pipeline routing, preset manager improvements
- Factory presets: cleanup and normalization

Fixes dashboard crash on disconnected state (dogfood issue #1)
2026-06-12 14:02:13 -04:00

6.7 KiB

Dogfood QA Report — Pi Multi-FX Pedal

Target: http://pedal.local:8080 (RPi live hardware) Date: 2026-06-12 Scope: REST API endpoints, HTML pages, Tone3000 search, edge cases vs live Pi Tester: Hermes Agent (automated exploratory QA against real deployment)


Executive Summary

Severity Count
🔴 Critical 1
🟠 High 2
🟡 Medium 1
🔵 Low 1
Total 5

Overall Assessment: The pedal is working! The Pi is online, connected, and serving real data. Dashboard shows live state (volume at 0.33, mono routing, preset system working). Three key issues identified: one critical (dashboard crash when disconnected), one version-sync gap (tonehub aliases not pushed to Pi), and one missing endpoint (/api/captures).


Live vs Local — Key Difference

Check Local (code test) Live Pi (pedal.local)
Dashboard 200 200 with real data
Connected state connected: False connected: True
master_volume 0.8 (default) 0.33 (live)
routing_mode mono mono, breakpoint 7
Tone3000 search Works Works
Tonehub alias routes Work 404 — not on Pi yet

Issues

Issue #1: Dashboard crashes with 500 when pedal deps not connected 🔴

(Same as previously reported and fixed locally — needs push to Pi)

Field Value
Severity 🔴 Critical
Category Functional
URL GET /

Description: The dashboard template renders fine when pedal deps are connected (tested live — returns 200 with real data), but crashes with HTTP 500 when the pedal is disconnected. Root cause: _gather_state() returns only {"connected": False} when deps are None, but the template expects full default keys.

Fix applied locally in _gather_state() — returns full defaults (master_volume: 0.8, routing_mode: "mono", etc.) when disconnected.

Needs: Commit & push to Pi.


Issue #2: React SPA calls /api/captures but backend has no such route 🟠

Field Value
Severity 🟠 High
Category Functional
URL GET /api/captures

Description: The React SPA (pi-multifx-pedal-ui/src/App.jsx) has an API layer that calls GET /api/captures to list NAM captures and POST /api/captures/upload to upload new ones. However, the backend (src/web/server.py) has no /api/captures route — returns 404 on both local test and live Pi.

Introduced during "Wire React Knobs to Live API" task — frontend calls were added without building the corresponding backend endpoints. The captures screen in the React UI will silently fail.


Issue #3: Tonehub alias routes not pushed to Pi 🟠

Field Value
Severity 🟠 High
Category Deployment
URL GET /api/tonehub/search

Description: The alias routes GET /api/tonehub/search and GET /api/tonehub/search/irs work locally (return Tone3000 search results) but return 404 on the live Pi. These routes were added in an uncommitted change on the local dev machine and were never pushed to Gitea, so the Pi doesn't have them.

The direct routes (/api/irs/tonedownload/search, /api/models/tonedownload/search) work on the Pi. Only the shorthand aliases are missing.

Affected routes:

  • GET /api/tonehub/search → 404 on Pi (alias for /api/models/tonedownload/search)
  • GET /api/tonehub/search/irs → 404 on Pi (alias for /api/irs/tonedownload/search)

Needs: Commit tonehub alias routes + _gather_state fix, push to Gitea, pull on Pi, restart server.


Issue #4: /api/block-params/{fx_type} returns 200 for unknown types 🟡

Field Value
Severity 🟡 Medium
Category Functional
URL GET /api/block-params/99

Description: GET /api/block-params/99 returns 200 with {"fx_type":"99","params":[]} instead of 404. The route accepts any string without validating against known FX types. Confirmed on live Pi (same behavior).


Issue #5: Unclosed aiohttp client session warnings 🔵

Field Value
Severity 🔵 Low
Category Console
URL All Tone3000 routes

Description: Unclosed aiohttp ClientSession on Tone3000 API calls — resource leak that accumulates warning noise. Same on both local and Pi.


Issues Summary Table

# Title Severity Type Status
1 Dashboard 500 when disconnected 🔴 Critical Functional Fixed locally — needs push
2 React calls /api/captures, backend missing 🟠 High Functional Needs new endpoint
3 Tonehub alias routes 404 on Pi 🟠 High Deployment Fixed locally — needs push
4 block-params 200 for unknown types 🟡 Medium Functional Needs validation
5 Unclosed aiohttp session 🔵 Low Console Needs cleanup

Testing Coverage

Pages (all 5 on Pi)

Page Status Notes
GET / (Dashboard) 200 Live data: master_volume=0.33
GET /presets 200 Returns bank 0 / Clean Jazz preset
GET /models 200 Empty (no models installed)
GET /irs 200 Empty (no IRs installed)
GET /settings 200 15KB, full settings UI

API Endpoints on Pi

Endpoint Result Notes
GET /api/state 200 connected: true
GET /api/presets 200 Real presets
GET /api/routing 200 mono, breakpoint 7
POST /api/routing 200 Returns updated routing
GET /api/irs 200 No IRs loaded
GET /api/models 200 No models loaded
GET /api/captures 404 Missing endpoint
GET /api/irs/tonedownload/search 200 36 results
GET /api/tonehub/search 404 Not pushed to Pi
GET /api/tonehub/search/irs 404 Not pushed to Pi
GET /api/block-params/0 200
GET /api/block-params/99 200 ⚠️ Should be 404
POST /api/bypass/toggle 404 Check if route exists
POST /api/tuner/toggle 404 Check if route exists
POST /api/models/tonedownload/install 422/500 ⚠️ Works locally, needs download target

Edge Cases

Test Result
GET /nonexistent 404
GET /api/nonexistent 404
GET /api/presets/99 404

Next Steps

  1. Commit & push the _gather_state fix and tonehub alias routes to Gitea
  2. Pull & restart on the Pi
  3. Build /api/captures endpoint (list captures + upload)
  4. Add FX type validation to GET /api/block-params/{fx_type}
  5. Run retest after fixes are deployed