{"record":{"id":"b294e55a641df30a","repo":"headroomlabs-ai/headroom","slug":"self-name-backend-does-not-support-openai-format","errorCode":null,"errorMessage":"{self.name} backend does not support OpenAI format","messagePattern":"(.+?) backend does not support OpenAI format","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"headroom/backends/base.py","lineNumber":141,"sourceCode":"        headers: dict[str, str],\n    ) -> BackendResponse:\n        \"\"\"Send an OpenAI-format message request.\n\n        Unlike send_message(), this takes OpenAI-format input and returns\n        OpenAI-format output (no Anthropic conversion). Optional - only\n        implemented by backends that support OpenAI-compatible APIs.\n\n        Args:\n            body: Request body in OpenAI chat completion format.\n            headers: Request headers.\n\n        Returns:\n            BackendResponse with body in OpenAI chat completion format.\n\n        Raises:\n            NotImplementedError: If backend doesn't support OpenAI format.\n        \"\"\"\n        raise NotImplementedError(f\"{self.name} backend does not support OpenAI format\")\n\n    async def stream_openai_message(\n        self,\n        body: dict[str, Any],\n        headers: dict[str, str],\n    ) -> AsyncIterator[str]:\n        \"\"\"Stream an OpenAI-format chat completion.\n\n        Yields SSE-formatted strings: 'data: {...}\\\\n\\\\n' for each chunk,\n        ending with 'data: [DONE]\\\\n\\\\n'.\n\n        Args:\n            body: Request body in OpenAI chat completion format (stream: true).\n            headers: Request headers.\n\n        Yields:\n            SSE-formatted strings ready to send to client.\n","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/backends/base.py#L123-L159","documentation":"The default Backend.handle_openai (base.py) raises NotImplementedError for backends that do not implement the OpenAI-compatible chat-completion format. Each backend subclass opts in by overriding the method; calling it on a backend that did not (e.g. a passthrough or native-format-only backend) hits the base stub.","triggerScenarios":"Calling backend.handle_openai(body, headers) on a Backend subclass that only implements the native/Anthropic-format methods, or routing OpenAI-format traffic to a backend whose class never overrode the OpenAI-format handler.","commonSituations":"Adding a new custom Backend subclass and forgetting to implement the OpenAI surface while the proxy front door speaks OpenAI format; pointing an OpenAI client at a backend that only supports its native API.","solutions":["Switch to a backend that supports OpenAI format (the error names the backend via self.name — check that class for which methods it overrides).","If you own the backend subclass, implement handle_openai (and stream_openai_message for streaming) to translate OpenAI bodies to the backend's native format.","If you own the caller, dispatch based on a capability flag instead of assuming every backend speaks OpenAI format."],"exampleFix":"# before\nresp = await backend.handle_openai(body, headers)  # NotImplementedError\n\n# after\nclass MyBackend(Backend):\n    async def handle_openai(self, body, headers):\n        native = to_native(body)\n        return BackendResponse(body=from_native(await self._call(native)))","handlingStrategy":"type-guard","validationCode":"from headroom.backends.base import Backend\n\ndef supports_openai(backend: Backend) -> bool:\n    return type(backend).handle_openai is not Backend.handle_openai\n\nif not supports_openai(backend):\n    raise SystemExit(f\"{backend.name} cannot serve OpenAI-format requests; pick another backend\")","typeGuard":"def supports_openai_format(b: object) -> bool:\n    \"\"\"True when the backend class overrides the OpenAI-format handler.\"\"\"\n    handle = getattr(type(b), \"handle_openai\", None)\n    return callable(handle) and getattr(handle, \"__module__\", \"\") != Backend.__module__ or handle is not Backend.handle_openai","tryCatchPattern":"try:\n    resp = await backend.handle_openai(body, headers)\nexcept NotImplementedError:\n    logger.error(\"backend %s lacks OpenAI-format support; rerouting\", backend.name)\n    raise  # or route to a capable backend","preventionTips":["Advertise capabilities per backend and route at the proxy layer instead of assuming universal OpenAI support.","When subclassing Backend, implement the full surface your front door uses or explicitly disable those routes.","Cover each backend with an integration test that sends one OpenAI-format request."],"tags":["python","backend","not-implemented","openai-compat"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}