Responses API streaming crashes with 'AsyncStream' object has no attribute 'id' when using .with_raw_response
Which component is this bug for?
OpenAI Instrumentation
Description
client.responses.with_raw_response.create(stream=True, ...) crashes async_responses_get_or_create_wrapper with:
AttributeError: 'AsyncStream' object has no attribute 'id'This is a variant of #4058 / PR #4078 that the fix didn't cover. #4078 taught parse_response/async_parse_response
to unwrap APIResponse/AsyncAPIResponse (used by .with_streaming_response), but .with_raw_response.create() on
Responses returns a LegacyAPIResponse (via openai._legacy_response.async_to_raw_response_wrapper), which was
already unwrapped before #4078. The problem isn't the unwrapping itself — it's that LegacyAPIResponse.parse(),
when the underlying request was stream=True, returns a Stream/AsyncStream instance, not a parsed Response.
The only isinstance(response, (Stream, AsyncStream)) check in async_responses_get_or_create_wrapper runs
before parsing, on the raw, unparsed return of wrapped():
When the call goes through .with_raw_response, that raw return is a LegacyAPIResponse wrapper, not a
Stream/AsyncStream, so the check misses it. Execution falls through, async_parse_response() calls
.parse() on it, which (per the self._stream branch in openai._legacy_response.LegacyAPIResponse._parse)
returns an AsyncStream. There's no post-parse recheck for Stream/AsyncStream, so it crashes reading .id:
This combination (.with_raw_response + stream=True) is exactly what agent_framework_openai (Microsoft Agent
Framework) uses as of >=1.6.0, to read the x-ms-served-model response header — so every agentic streaming turn
instrumented with this package crashes.
Reproduction steps
Self-contained (mocks the HTTP transport, no API key needed):
import asyncio
import httpx
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry import trace
trace.set_tracer_provider(TracerProvider())
OpenAIInstrumentor().instrument()
from openai import AsyncOpenAI # noqa: E402
SSE_BODY = (
b'event: response.created\n'
b'data: {"type":"response.created","response":{"id":"resp_123","object":"response",'
b'"created_at":0,"status":"in_progress","model":"gpt-4o-mini","output":[]}}\n\n'
b'event: response.completed\n'
b'data: {"type":"response.completed","response":{"id":"resp_123","object":"response",'
b'"created_at":0,"status":"completed","model":"gpt-4o-mini","output":[],'
b'"usage":{"input_tokens":1,"output_tokens":1,"total_tokens":2}}}\n\n'
)
def handler(request: httpx.Request) -> httpx.Response:
return httpx.Response(
200,
headers={"content-type": "text/event-stream", "x-ms-served-model": "gpt-4o-mini"},
content=SSE_BODY,
)
async def main():
client = AsyncOpenAI(api_key="sk-test", http_client=httpx.AsyncClient(transport=httpx.MockTransport(handler)))
raw = await client.responses.with_raw_response.create(
model="gpt-4o-mini",
input="hello",
stream=True,
)
stream = raw.parse()
async for event in stream:
pass
print("no crash")
asyncio.run(main())Expected behavior
No crash — either trace the stream normally (matching the non-with_raw_response path) or skip tracing gracefully.
Actual Behavior
Reproduced on both:
opentelemetry-instrumentation-openai==0.62.3+openai==2.50.0opentelemetry-instrumentation-openai==0.62.3+openai==3.14.1(latest)
File ".../opentelemetry/instrumentation/openai/v1/responses_wrappers.py", line 746, in async_responses_get_or_create_wrapper
existing_data = responses.get(parsed_response.id)
^^^^^^^^^^^^^^^^^^
AttributeError: 'AsyncStream' object has no attribute 'id'Python Version
3.12
Additional context
We're currently working around this in our own codebase by unwrapping just the Responses API span instrumentation
after OpenAIInstrumentor().instrument() runs.
Are you willing to submit PR?
Yes I am willing to submit a PR if someone can confirm my assessment of the issue.
Source: traceloop/openllmetry