Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

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

Ouverte
#2,039 0 commentaires 0 réactions 1 personne assignée Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@hassiebp y travaille déjà.

Depuis le 22/10/2026.

  • #2056 par @Boulea7 — ouverte

Évaluation

Cette issue n'a pas encore été évaluée.

Description

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?

Langage dominant
Python
Étoiles
502
Forks
381
Merge moyen
1 j 1 h
PR mergées (30 j)
64

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de langfuse/langfuse-python

Toutes les issues de langfuse/langfuse-python

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.