The problem

x402 settles payment before the handler runs. So when an upstream image provider times out, the buyer has already paid and there's nothing to hand back.

That part is unavoidable. What wasn't: our image endpoints were reporting those failures as 424. A 4xx says the caller got it wrong. The reconciler reads 4xx and moves on, the fast-health detector ignores it, and the buyer eats the cost of our dependency going down.

The rest of the portfolio already had this right. _shared/news-lite.ts spells it out: an upstream timeout is our dependency failing, not bad input, so it has to surface as a 5xx where the reconciler will treat it as a refund candidate.

What changed

Dependency failures in upscale-image, qwen-image (served through image-generate-pro) and image-to-video now return 503.

Caller mistakes are untouched. A malformed request still gets 400 or 422, a rate limit still gets 429, and a missing API key on our side still gets 500. Only the "our upstream fell over" path moved.

Behind the status codes we found two real bugs and one phantom.

qwen-image was failing about two calls in three. Not a parsing bug. Venice just needs longer than the 75 second budget it had, so that's now 120 seconds.

upscale-image had a 45 second fetch timeout and no overall ceiling, which is thin for a 4x upscale. Now 90 seconds, with a 150 second overall timer matching the pro handler.

image-to-video was never broken. Our own health checker tested a regex for the word image before the one for video, and the slug image-to-video contains image. So a working video endpoint got graded as an image endpoint that returned no image, complete with a 0x0 dimension reading. The check now tests video and audio first.

Why it matters if you're buying

A paid call that fails now looks like a failure to every system that watches it. Refund reconciliation sees it, health monitoring sees it, and the directory sees an honest error rate instead of a 4xx that reads as your fault.

If you were seeing sporadic empty results from qwen-image, try it again.