traceloop / traceloop/openllmetry
๐ Bug Report: MCP `InstrumentedStreamWriter.send()` assumes dict-shaped `request.result` and can fail for object/model results
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 7.4k
- Forks
- 1.1k
- Avg merge
- 8d 14h
- Merged PRs (30d)
- 2
Description
Which component is this bug for?
Traceloop SDK
๐ Description
In opentelemetry-instrumentation-mcp, InstrumentedStreamWriter.send() assumes request.result is always a dict:
if "isError" in request.result:
if request.result["isError"] is True:
span.set_status(
Status(
StatusCode.ERROR,
f"{request.result['content'][0]['text']}",
)
)
Impact
- Response-stream error handling can fail at runtime
- Error spans may not be set correctly
- Behavior is inconsistent across MCP instrumentation paths
Possible errors
TypeError: argument of type 'X' is not iterableTypeError: 'X' object is not subscriptableKeyError: 'content'IndexError: list index out of range
File
packages/opentelemetry-instrumentation-mcp/opentelemetry/instrumentation/mcp/instrumentation.py
Method
InstrumentedStreamWriter.send()
Proposed fix
Normalize request.result access before reading fields:
- use
.get(...)for dicts - use
getattr(...)for objects
๐ Reproduction steps
- Use MCP instrumentation with a response/result object that exposes fields via attributes rather than dict keys.
- Trigger a response where the MCP result represents an error.
- Exercise the InstrumentedStreamWriter.send() path.
- Observe failure or missing error handling around:
request.result["content"][0]["text"]
๐ Expected behavior
The stream writer should support both of these shapes:
dict-style
request.result["isError"]
request.result["content"][0]["text"]
object-style
request.result.isError
request.result.content[0].text
without crashing, and should always set the span status correctly for MCP error responses.
๐ Actual Behavior with Screenshots
The code currently assumes only dict-style access in InstrumentedStreamWriter.send().
This causes inconsistent handling and can break when request.result is not a dict.
๐ค Python Version
No response
๐ Provide any additional context for the Bug.
No response
๐ Have you spent some time to check if this bug has been raised before?
- I checked and didn't find similar issue
Are you willing to submit PR?
None
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up โ it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/opentelemetry-instrumentation-mcp/opentelemetry/instrumentation/mcp/instrumentation.py, focusing on InstrumentedStreamWriter.send(). Reproduce the error-handling path with both dict-style and object-style request.result values, then verify that the stream writer does not crash and sets the span status correctly for MCP error responses.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100