Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

bug(openai): a stream that fails mid-iteration ends the generation without level ERROR

Offen
#2,039 0 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@hassiebp arbeitet bereits daran.

Seit 22.10.2026.

  • #2056 von @Boulea7 — offen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Beschreibung

bug integration-openai sdk-python
Describe the bug

When an OpenAI chat stream fails after the first chunk, the generation ends with no level and no status_message. The caller gets openai.APIError, while Langfuse shows a normal generation holding the partial output. The same failure before the stream starts is recorded as ERROR.

The cause is in langfuse/openai.py. _wrap catches only what create() raises. Exceptions raised while iterating go through traced_iterator's finally (line 1112) into _finalize_stream_response, which calls generation.end() with no error. The async path (_instrument_openai_async_stream) and LangfuseResponseGeneratorSync/Async do the same.

To reproduce
import httpx
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
from langfuse import Langfuse
from langfuse.openai import OpenAI

exporter = InMemorySpanExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
Langfuse(public_key="pk", secret_key="sk", base_url="http://127.0.0.1:9", tracer_provider=provider)

SSE = (
    b'data: {"id":"c1","object":"chat.completion.chunk","created":1,"model":"gpt-4o-mini",'
    b'"choices":[{"index":0,"delta":{"role":"assistant","content":"Hel"},"finish_reason":null}]}\n\n'
    b'data: {"error":{"message":"The server had an error while processing your request.","type":"server_error"}}\n\n'
)
client = OpenAI(api_key="x", http_client=httpx.Client(transport=httpx.MockTransport(
    lambda r: httpx.Response(200, headers={"content-type": "text/event-stream"}, content=SSE))))

stream = client.chat.completions.create(name="failed-stream", model="gpt-4o-mini",
                                        messages=[{"role": "user", "content": "hi"}], stream=True)
try:
    for chunk in stream:
        pass
except Exception as e:
    print("caller saw  :", type(e).__name__, e)

a = next(s for s in exporter.get_finished_spans() if s.name == "failed-stream").attributes
print("level       :", a.get("langfuse.observation.level"))
print("status_msg  :", a.get("langfuse.observation.status_message"))
print("output      :", a.get("langfuse.observation.output"))
$ python lf_stream_error.py 2>/dev/null
caller saw  : APIError The server had an error while processing your request.
level       : None
status_msg  : None
output      : Hel

With the transport answering 500 to create(stream=True) instead, the generation records ERROR | Error code: 500 - {'error': {'message': 'server_error'}}. The AsyncOpenAI version of the failing stream also prints level: None.

Expected

level="ERROR" and status_message=str(error) on the generation, with the partial output and any usage kept. The OpenAI integration docs say Langfuse "automatically tracks and monitors OpenAI API errors" in level and statusMessage, and test_chat_completion_error_marks_generation_error pins that for the non-streaming case.

SDK versions

langfuse 5.0.2 at 81c457c, openai 3.35.1, opentelemetry-sdk 1.45.1, Python 3.12. Not checked: the Responses API, where a response.failed event raises nothing.

@hassiebp I'd catch the exception in each iterator wrapper, set the error on the generation, and re-raise. A test using the SSE body above can live next to the existing break test in tests/unit/test_openai.py. Shall I open that PR?

Vorherrschende Sprache
Python
Sterne
502
Forks
381
Ø Merge
1 T. 1 Std.
Gemergte PRs (30 T.)
64

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus langfuse/langfuse-python

Alle Issues in langfuse/langfuse-python

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.