{"record":{"id":"1b2738ad577d6832","repo":"BerriAI/litellm","slug":"error-parsing-bfl-response-e","errorCode":null,"errorMessage":"Error parsing BFL response: {e}","messagePattern":"Error parsing BFL response: (.+?)","errorType":"exception","errorClass":"BlackForestLabsError","httpStatus":null,"severity":"error","filePath":"litellm/llms/black_forest_labs/image_edit/transformation.py","lineNumber":297,"sourceCode":"        # BFL uses JSON, not multipart - return empty files\n        return request_body, []\n\n    def transform_image_edit_response(\n        self,\n        model: str,\n        raw_response: httpx.Response,\n        logging_obj: LiteLLMLoggingObj,\n    ) -> ImageResponse:\n        \"\"\"\n        Transform Black Forest Labs response to OpenAI-compatible ImageResponse.\n\n        This is called with the FINAL polled response (after handler does polling).\n        The response contains: {\"status\": \"Ready\", \"result\": {\"sample\": \"https://...\"}}\n        \"\"\"\n        try:\n            response_data: Final = raw_response.json()\n        except Exception as e:\n            raise BlackForestLabsError(\n                status_code=raw_response.status_code,\n                message=f\"Error parsing BFL response: {e}\",\n            )\n\n        # Get image URL from result\n        image_url: Final = response_data.get(\"result\", {}).get(\"sample\")\n        if not image_url:\n            raise BlackForestLabsError(\n                status_code=500,\n                message=\"No image URL in BFL result\",\n            )\n\n        # Build ImageResponse\n        return ImageResponse(\n            created=int(time.time()),\n            data=[ImageObject(url=image_url)],\n        )\n","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/black_forest_labs/image_edit/transformation.py#L279-L315","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Retry the request once - a truncated/rewritten 200 body is usually transient.","Capture `raw_response.text` (via your logging hook or verbose mode) to see what actually came back (HTML? empty? partial JSON?).","If a proxy sits between you and BFL, bypass it or add it to the allowlist for the polling domain.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from litellm.llms.black_forest_labs.common_utils import BlackForestLabsError\n\ntry:\n    resp = litellm.image_edit(model=\"flux-kontext-pro\", image=img, prompt=p)\nexcept BlackForestLabsError as e:\n    if \"Error parsing BFL response\" in str(e):\n        resp = retry_with_backoff(lambda: litellm.image_edit(\n            model=\"flux-kontext-pro\", image=img, prompt=p), attempts=2)\n    else:\n        raise","preventionTips":["Keep direct egress to the BFL polling domain; avoid rewriting proxies on that path.","Enable litellm verbose logging so raw non-JSON bodies are observable when this fires.","Wrap generation calls in a one-retry policy for parse-stage failures."],"tags":["litellm","black-forest-labs","flux","image-edit","json","response-parsing","proxy"],"backgroundTag":"invalid-json-response","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}