odysseus-dev/odysseus · error · HTTPException
Image edit request failed
Error message
Image edit request failed
What it means
Raised when the self-hosted /v1/images/edits call returns a status other than 200/404/405 (and not the specific 'does not support image edits' 400 that triggers fallback). The upstream status is forwarded and the detail is taken from the response's detail or error JSON field if parseable.
Source
Thrown at routes/gallery/gallery_routes.py:1489
logger.warning("inpaint_proxy self-hosted edits: status %s", r.status_code)
detail = "Image edit request failed"
try:
err = r.json()
detail = err.get("detail") or err.get("error") or detail
except Exception:
pass
# A plain SD/SDXL checkpoint often exposes
# generation only at /images/edits.
# That does not mean the endpoint cannot inpaint:
# Odysseus diffusion_server.py has a dedicated
# /images/inpaint route that can derive/fallback to
# inpaint, img2img crop+composite, or txt2img
# crop+composite. Fall through to that route instead
# of surfacing "does not support image edits".
if r.status_code == 400 and "does not support image edits" in str(detail).lower():
logger.info("inpaint_proxy self-hosted edits unsupported; falling back to /images/inpaint")
else:
raise HTTPException(r.status_code, detail)
except HTTPException:
raise
except Exception:
logger.exception("inpaint_proxy: failed to prepare self-hosted edit request")
raise HTTPException(400, "Failed to prepare inpaint request")
r = await client.post(_join_checked_gallery_endpoint(base, "/images/inpaint"), json=body)
if r.status_code != 200:
logger.error("inpaint_proxy diffusion: status %s", r.status_code)
raise HTTPException(r.status_code, "Inpaint request failed")
return r.json()
except httpx.TimeoutException:
raise HTTPException(504, "Inpaint request timed out (240s)")
except HTTPException:
raise
except Exception:
logger.exception("inpaint_proxy: request failed")
raise HTTPException(502, "Inpaint request failed")View on GitHub (pinned to f9235ebbf1)
Solutions
- Read the forwarded status/detail and check the diffusion server logs for the matching request failure.
- If 503/model-loading, wait for the model to finish loading and retry.
- If 422, compare the multipart fields the proxy sends (model, prompt, size, n, image, mask) with what the server's /images/edits expects.
- If 500 with CUDA OOM, lower resolution or free VRAM on the diffusion host.
Defensive patterns
Strategy: try-catch
Try / catch
try:
r = await client.post("/api/image/inpaint", json=payload)
if r.status_code >= 400:
detail = r.json().get("detail", "")
if r.status_code == 503:
await wait_model_loaded(base); r = await client.post(...) # retry after load
else:
raise RuntimeError(f"diffusion server rejected edit: {r.status_code} {detail}")
except httpx.HTTPError as e:
raise RuntimeError(f"edit request transport failed: {e}") from e Prevention
- Health-check the diffusion server (GET / or /internal/ping) before submitting edits.
- Wait for model load on fresh server start before sending work.
- Keep auth and payload schema aligned between proxy and server.
When it happens
Trigger: POST to {base}/images/edits on the local diffusion path returning 401/403 (auth enabled), 422 (validation of the multipart payload), 500 (generation crash), or 503 (model still loading).
Common situations: Diffusion server restarted and the model checkpoint is loading (503); the wrapper added API auth the proxy does not send; schema drift in the multipart fields; CUDA OOM surfacing as 500.
Related errors
- OpenAI edit failed
- Inpaint request failed
- Session request returned an invalid response
- GitHub device-code request failed (HTTP {status})
- GitHub device-code request failed: {e}
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/349551f4769b3dc7.
Report an issue: GitHub.