BerriAI/litellm · error · BlackForestLabsError

Error parsing BFL response

Error message

Error parsing BFL response: {e}

What it means

After the BFL polling loop returns the final 'Ready' response, `transform_image_edit_response` calls `raw_response.json()` to extract `result.sample`. If that parse throws (body is not valid JSON), the error is wrapped in a `BlackForestLabsError` carrying the HTTP status code of the poll response. It means the final poll returned HTTP 200 with a non-JSON body, or a body encoding httpx cannot decode.

Solutions

  1. Retry the request once - a truncated/rewritten 200 body is usually transient.
  2. Capture `raw_response.text` (via your logging hook or verbose mode) to see what actually came back (HTML? empty? partial JSON?).
  3. If a proxy sits between you and BFL, bypass it or add it to the allowlist for the polling domain.
  4. If reproducible, check the BFL status page / API docs for response-format changes and update LiteLLM to the latest version in case the contract handling changed.
Defensive patterns

Strategy: retry

Try / catch

from litellm.llms.black_forest_labs.common_utils import BlackForestLabsError

try:
    resp = litellm.image_edit(model="flux-kontext-pro", image=img, prompt=p)
except BlackForestLabsError as e:
    if "Error parsing BFL response" in str(e):
        resp = retry_with_backoff(lambda: litellm.image_edit(
            model="flux-kontext-pro", image=img, prompt=p), attempts=2)
    else:
        raise

Prevention

When it happens

Trigger: The BFL gateway (e.g. gateway.bfl.ai) returns an HTML error/landing page, empty body, or truncated gzip stream with status 200; a corporate proxy or middlebox rewrites the poll response; a flaky connection truncates the JSON mid-transfer so json() raises JSONDecodeError.

Common situations: Self-hosted or regional BFL endpoints behind an ingress that returns HTML on overload; TLS-terminating proxies that inject error pages; rare transient truncation. Very uncommon with the production api.bfl.ai/gateway.bfl.ai path - suspect infrastructure in between when you see it.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/1b2738ad577d6832. Report an issue: GitHub.

Appendix: source

Thrown at litellm/llms/black_forest_labs/image_edit/transformation.py:297

        # BFL uses JSON, not multipart - return empty files
        return request_body, []

    def transform_image_edit_response(
        self,
        model: str,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,
    ) -> ImageResponse:
        """
        Transform Black Forest Labs response to OpenAI-compatible ImageResponse.

        This is called with the FINAL polled response (after handler does polling).
        The response contains: {"status": "Ready", "result": {"sample": "https://..."}}
        """
        try:
            response_data: Final = raw_response.json()
        except Exception as e:
            raise BlackForestLabsError(
                status_code=raw_response.status_code,
                message=f"Error parsing BFL response: {e}",
            )

        # Get image URL from result
        image_url: Final = response_data.get("result", {}).get("sample")
        if not image_url:
            raise BlackForestLabsError(
                status_code=500,
                message="No image URL in BFL result",
            )

        # Build ImageResponse
        return ImageResponse(
            created=int(time.time()),
            data=[ImageObject(url=image_url)],
        )

View on GitHub (pinned to 77b7c6c40c)