bug(openai): a stream that fails mid-iteration ends the generation without level ERROR
Mantenedores costumam responder em até 1 dia
Avaliação
Esta issue ainda não foi avaliada.
Descrição
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?
- Linguagem predominante
- Python
- Estrelas
- 502
- Forks
- 381
- Merge médio
- 1d 1h
- PRs com merge (30d)
- 64
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de langfuse/langfuse-python
-
bug(scores): create_score sends numpy.bool_ as JSON `true` and Decimal as "<Decimal>" since v5.0.2Talvez já em andamento @lalith0407 assumiu há 3 dias. Abertabug feat-scores sdk-python
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
langfuse/langfuse-python#2057 ·
Mantenedores costumam responder em até 1 dia
-
tests/unit/test_prompt.py fails on a fresh clone without LANGFUSE_* env varsTalvez já em andamento @Mathoholic assumiu há 16 dias. Abertabug feat-prompt-management sdk-python
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 80/100
langfuse/langfuse-python#1976 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
-
fix(serializer): handle single-string __slots__ and detect cycles in slotted objectsTalvez já em andamento @hassiebp assumiu há 11 dias. Abertabug sdk-python
langfuse/langfuse-python#2014 · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
bug: ChatPromptClient.compile appends str(whole list) once per non-dict placeholder itemTalvez já em andamento @nimarb assumiu há 6 dias. Abertabug feat-prompt-management sdk-python
langfuse/langfuse-python#1971 · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
bug: GCS upload detection in MediaManager uses substring match on the full URLTalvez já em andamento @hassiebp assumiu há 27 dias. Abertabug feat-multimodal-media sdk-python
langfuse/langfuse-python#1913 · 1 comentário · 1 responsável ·
Mantenedores costumam responder em até 1 dia
Todas as issues de langfuse/langfuse-python
Issues semelhantes
-
fix(ui): serve bundled fonts from the gatewayTalvez já em andamento @dkritarth assumiu hoje. Abertaagent: in-progress agent: ready P3 type: bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
dkritarth/scopewatch#336 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
bob
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 72/100
khuisman/mcp-gee-sweet#1267 ·
Mantenedores costumam responder em até 1 dia
-
bug confirmed issue
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
open-webui/open-webui#33285 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
tv-list
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 66/100
Gathin23/cleanyourtv#2337 ·
Mantenedores costumam responder em até 1 dia
-
bug P2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
Mantenedores costumam responder em até 1 dia