odysseus-dev/odysseus · error · HTTPException

This MLX image endpoint supports text-to-image generation on

Error message

This MLX image endpoint supports text-to-image generation only. Use /v1/images/generations, or serve an edit/img2img-capable model.

What it means

Raised at the end of /v1/images/edits (and mirrored in /v1/images/harmonize) in scripts/mlx_image_server.py with HTTP 422 when the active model is not an edit-capable one (not DDColor, not LaMa/MI-GAN). The MLX server only supports edits for colorize/inpaint models; with a generation-only model (FLUX/HiDream/Boogu) the edits endpoint refuses up front.

Source

Thrown at scripts/mlx_image_server.py:413

):
    active_model = model or _args.model
    if _is_lama_inpaint(active_model) or _is_ddcolor(active_model):
        image_raw = await image.read()
        mask_raw = await mask.read() if mask is not None else None
        out_images = []
        count = max(1, min(int(n or 1), 4))
        for _ in range(count):
            with tempfile.TemporaryDirectory(prefix="odysseus-mlx-edit-") as td:
                out_path = Path(td) / "image.png"
                if _is_ddcolor(active_model):
                    _run_ddcolor_bridge(active_model, image_raw, out_path)
                else:
                    _run_inpaint_bridge(active_model, image_raw, mask_raw, out_path)
                if not out_path.exists():
                    raise HTTPException(500, f"MLX Swift bridge completed but did not write {out_path}")
                out_images.append({"b64_json": base64.b64encode(out_path.read_bytes()).decode("ascii")})
        return {"created": 0, "data": out_images}
    raise HTTPException(
        422,
        "This MLX image endpoint supports text-to-image generation only. "
        "Use /v1/images/generations, or serve an edit/img2img-capable model.",
    )


@app.post("/v1/images/harmonize")
def harmonize_image(req: HarmonizeRequest):
    active_model = _args.model
    if _is_lama_inpaint(active_model) or _is_ddcolor(active_model):
        try:
            image_raw = base64.b64decode(req.image.split(",", 1)[-1])
            mask_b64 = req.body_mask or req.mask
            mask_raw = base64.b64decode(mask_b64.split(",", 1)[-1]) if mask_b64 else None
        except Exception as e:
            raise HTTPException(400, f"Invalid base64 image payload: {e}") from e
        with tempfile.TemporaryDirectory(prefix="odysseus-mlx-harmonize-") as td:
            out_path = Path(td) / "image.png"

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Use POST /v1/images/generations for these models (prompt-only)
  2. Relaunch the server with an edit-capable model (LaMa/MI-GAN inpaint or DDColor colorize) to serve /v1/images/edits
  3. If you need diffusion img2img, use the diffusers-based diffusion_server.py instead, which supports pipelines accepting an image argument

Example fix

# before: server launched with --model black-forest-labs/FLUX.1-schnell
client.images.edit(image=f, prompt='...')  # 422
# after
client.images.generate(prompt='...')  # or relaunch server with a lama/migan/ddcolor model
Defensive patterns

Strategy: type-guard

Validate before calling

def is_edit_capable(model: str) -> bool:
    m = model.lower()
    return 'lama' in m or 'migan' in m or 'mi-gan' in m or 'ddcolor' in m

if not is_edit_capable(active_model):
    use_generations_endpoint()  # skip the edits call entirely

Type guard

def supports_mlx_edits(model: str) -> bool:
    m = model.lower()
    return any(k in m for k in ('lama', 'migan', 'mi-gan', 'ddcolor'))

Try / catch

try:
    r = client.images.edit(image=f, prompt=p)
except HTTPException as e:
    if e.status_code == 422 and 'text-to-image generation only' in str(e.detail):
        r = client.images.generate(prompt=p)
    else:
        raise

Prevention

When it happens

Trigger: POST /v1/images/edits while the server runs with --model pointing at an mflux/HiDream/Boogu generation model, so both _is_ddcolor(active_model) and the inpaint branch fail and control falls through to this raise. Same for /v1/images/harmonize with such a model.

Common situations: Pointing an OpenAI-compatible client's images.edit call at a text-to-image MLX server; expecting img2img from flux-schnell which the server never routes to edits; model string not containing the lama/migan/ddcolor tokens the classifiers look for.

Related errors


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