odysseus-dev/odysseus · error · HTTPException

Inpaint request failed

Error message

Inpaint request failed

What it means

Raised when the fallback POST to the self-hosted /v1/images/inpaint JSON endpoint returns a non-200 status. The upstream status code is forwarded with detail 'Inpaint request failed'; the route logs 'inpaint_proxy diffusion: status %s' first.

Source

Thrown at routes/gallery/gallery_routes.py:1499

                        # 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")

    # ---- POST /api/image/harmonize — proper img2img call ----
    # Earlier version routed through inpaint with a full-white mask, but
    # most backends interpret "100% mask coverage" as "regenerate from
    # scratch using the prompt", ignoring the source. Real img2img sends
    # the image alongside a `strength` (denoising strength) and the model
    # mixes that fraction of new noise into the existing pixels.
    @router.post("/api/image/harmonize")
    async def harmonize_image(request: Request):
        """Harmonize = img2img. The model preserves (1 - strength) of the

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Check diffusion server logs for the failed /v1/images/inpaint call and its exception.
  2. Verify the loaded model supports inpainting or that the server's img2img/txt2img crop+composite fallback is enabled.
  3. Align the JSON fields the proxy sends (image, mask, prompt, model, size/n) with diffusion_server.py's /images/inpaint schema.
  4. Free VRAM / restart the diffusion server if 500s stem from CUDA errors.
Defensive patterns

Strategy: try-catch

Validate before calling

async def inpaint_route_ready(base: str) -> bool:
    try:
        async with httpx.AsyncClient(timeout=10) as c:
            r = await c.post(f"{base}/v1/images/inpaint", json={})
            # 422 = route exists, payload rejected; 404 = route missing
            return r.status_code != 404
    except httpx.HTTPError:
        return False

Try / catch

try:
    r = await client.post("/api/image/inpaint", json=payload)
    r.raise_for_status()
except httpx.HTTPStatusError as e:
    if e.response.status_code >= 500:
        # upstream pipeline failure — check diffusion server logs
        raise RuntimeError("diffusion inpaint failed server-side") from e
    raise

Prevention

When it happens

Trigger: The diffusion server's dedicated /images/inpaint route rejecting the JSON body: 422 (missing fields like image/mask/prompt), 500 (inpaint pipeline not available for the loaded checkpoint), or 400 (bad dimensions).

Common situations: Loaded checkpoint has no inpaint pipeline and the server's derive/fallback logic fails; the JSON body schema expected by diffusion_server.py differs from what the proxy sends; model loading/OOM on the GPU host.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/4bed0afc859142b2. Report an issue: GitHub.