Found while speccing the MoQ surface (#24). Two pre-existing defects, neither caused by that work.
1. Every existing 402 in openapi.yaml models the wrong body
/render, /av/remux and /av/demux all $ref the Error schema for their 402 response. Production does not return the Error envelope on a 402. Observed shape:
{
"error": "payment required",
"error_detail": { ...the normalized WAVE error... },
"x402Version": 1,
"accepts": [ ... ],
"next_action": { ... }
}
error is a plain string, and the normalized WAVE error is nested under error_detail, alongside the x402 fields. So a generated SDK client that deserializes a 402 into Error will fail or silently produce garbage on the single most common failure a new developer hits — the paywall.
PR #30 adds correct X402PaymentRequired + X402Accepts schemas and a reusable PaymentRequired response. It deliberately did not rewrite the three existing endpoints — that is this issue. They should adopt the new response.
2. 401 is effectively unreachable on the MoQ routes
The code implies an unauthenticated or bad-key caller gets 401 AUTH_REQUIRED. Production returns 402 for both no-key and a syntactically-valid-but-unrecognized bearer — the x402 challenge is offered ahead of key rejection.
Worth a deliberate decision rather than leaving it as emergent behaviour: is offering payment before rejecting an unknown key the intent? It is defensible (it lets an anonymous caller pay their way in without ever holding a key, which is the x402 thesis) but it means a developer with a typo'd key sees "payment required" instead of "bad key" — a confusing first-run experience and a support-ticket generator.
Related, same ordering: a malformed ns/track never reaches its 400, because the 402 gate fires first. MOQ_JOIN_BAD_RESOURCE is only observable by an already-authorized caller. The spec documents this; worth confirming it is intended.
Done when
The three existing 402s reference the correct schema, a generated client round-trips a real 402 body without error, and the 401-vs-402 ordering is either changed or explicitly documented as intended.
Found while speccing the MoQ surface (#24). Two pre-existing defects, neither caused by that work.
1. Every existing 402 in
openapi.yamlmodels the wrong body/render,/av/remuxand/av/demuxall$reftheErrorschema for their 402 response. Production does not return theErrorenvelope on a 402. Observed shape:{ "error": "payment required", "error_detail": { ...the normalized WAVE error... }, "x402Version": 1, "accepts": [ ... ], "next_action": { ... } }erroris a plain string, and the normalized WAVE error is nested undererror_detail, alongside the x402 fields. So a generated SDK client that deserializes a 402 intoErrorwill fail or silently produce garbage on the single most common failure a new developer hits — the paywall.PR #30 adds correct
X402PaymentRequired+X402Acceptsschemas and a reusablePaymentRequiredresponse. It deliberately did not rewrite the three existing endpoints — that is this issue. They should adopt the new response.2. 401 is effectively unreachable on the MoQ routes
The code implies an unauthenticated or bad-key caller gets
401 AUTH_REQUIRED. Production returns 402 for both no-key and a syntactically-valid-but-unrecognized bearer — the x402 challenge is offered ahead of key rejection.Worth a deliberate decision rather than leaving it as emergent behaviour: is offering payment before rejecting an unknown key the intent? It is defensible (it lets an anonymous caller pay their way in without ever holding a key, which is the x402 thesis) but it means a developer with a typo'd key sees "payment required" instead of "bad key" — a confusing first-run experience and a support-ticket generator.
Related, same ordering: a malformed
ns/tracknever reaches its 400, because the 402 gate fires first.MOQ_JOIN_BAD_RESOURCEis only observable by an already-authorized caller. The spec documents this; worth confirming it is intended.Done when
The three existing 402s reference the correct schema, a generated client round-trips a real 402 body without error, and the 401-vs-402 ordering is either changed or explicitly documented as intended.