muse mist read: owner/ID form sends request to wrong API path
Background
muse mist read accepts two input forms:
- Bare ID:
muse mist read H7XFVEzeDfqk - Owner-qualified:
muse mist read gabriel/H7XFVEzeDfqk
The help text and docstring both document the owner/ID form as valid. But when
run_read detects a / in the input, it constructs the wrong API path:
# muse/cli/commands/mist.py:616 — BUG
api_path = f"/api/{owner_part}/mists/{id_part}"
The server has no route at /api/{owner}/mists/{id}. The real route is
GET /api/mists/{mist_id} — owner is not part of the API path. The result is
an HTTP 404 that surfaces to the user as:
❌ Hub returned HTTP 0: Server returned invalid JSON: Expecting value: line 1 column 1 (char 0)
The error message is also misleading: the underlying 404 body is
{"detail": "Not Found"} — valid JSON — but the CLI swallows the HTTP status
and reports a JSON parse failure instead.
Root cause
run_read is the only mist command that got the path wrong. Every other command
that handles owner/ID input correctly discards the owner and routes to
/api/mists/{id}:
| Command | Line | Path built | Correct? |
|---|---|---|---|
run_read |
616 | /api/{owner}/mists/{id} |
❌ bug |
run_delete |
903 | /api/mists/{id} |
✅ |
run_update |
994 | /api/mists/{id} |
✅ |
run_forks |
1053 | /api/mists/{id}/forks |
✅ |
run_raw |
1113 | /api/mists/{id}/raw |
✅ |
run_embed |
811 | /api/{owner}/mists/{id}/embed |
✅ (embed route intentionally needs owner) |
The run_fork command (line 690–696) was also checked — it correctly extracts
just the id_part for /api/mists/{id}/fork.
Goal
muse mist read gabriel/H7XFVEzeDfqk --hub https://staging.musehub.ai --json
returns the mist JSON. Both the bare-ID and the owner/ID form work identically.
Phases
Phase 1 — Fix run_read
One-line change in muse/cli/commands/mist.py.
Deliverable
[ ]
MR_01— Change line 616:# Before api_path = f"/api/{owner_part}/mists/{id_part}" # After api_path = f"/api/mists/{id_part}"The
owner_partvariable becomes unused; remove the assignment too (lines 613–614 can simplify to extracting onlyid_part).
Phase 2 — Fix the misleading 404 error message
When _hub_api receives a non-2xx response, the caller sees a JSON-parse error
instead of the actual HTTP status. The error should surface the HTTP status code
and the response body so the user can diagnose it.
Deliverable
- [ ]
MR_02—_hub_api(or its caller inrun_read) raises a clear error on non-2xx HTTP:❌ Hub returned HTTP 404: {"detail": "Not Found"}. The current"Server returned invalid JSON"message must not appear for a response that actually contains valid JSON.
Phase 3 — Tests
No test currently exercises run_read with the owner/ID form. Add tests to
prevent regression.
Deliverables
- [ ]
MR_03— Unit test:run_readwith"gabriel/H7XFVEzeDfqk"calls_hub_apiwith path/api/mists/H7XFVEzeDfqk(not/api/gabriel/mists/…). Mock_hub_apiand assert theapi_pathargument. - [ ]
MR_04— Unit test:run_readwith bare"H7XFVEzeDfqk"calls_hub_apiwith path/api/mists/H7XFVEzeDfqk. Existing happy-path smoke, now with explicit path assertion. - [ ]
MR_05— Unit test:run_readwith"owner/ID"does NOT include the owner in the path — theownerportion is silently discarded (it is advisory information only; the ID alone uniquely identifies a mist). - [ ]
MR_06— Unit test: when_hub_apireceives a 404,run_readexits with a message containing the HTTP status code (validates MR_02 fix).
Phase 4 — Staging smoke
- [ ]
MR_07—muse mist read gabriel/H7XFVEzeDfqk --hub https://staging.musehub.ai --jsonreturns the mist JSON withmist_id == "H7XFVEzeDfqk". - [ ]
MR_08—muse mist read H7XFVEzeDfqk --hub https://staging.musehub.ai --jsonreturns identical output (both forms are equivalent).
Acceptance criteria
muse mist read owner/IDandmuse mist read IDreturn identical JSON output.- HTTP 404 from the server surfaces as
❌ Hub returned HTTP 404: …— not a JSON parse error. - MR_03–MR_06 tests green.
- Staging smoke passes (MR_07–MR_08).
Out of scope
- Validating that the owner in
owner/IDmatches the mist's actual owner (the server owns that check; the CLI's job is just to extract the ID) - Changing the server-side routes
- Other mist subcommands — all others already handle
owner/IDcorrectly