fix(traceloop-sdk): avoid calling async json methods in JSONEncoder - #3968
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdded synchronous and asynchronous tests verifying workflow argument serialization for objects with a Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/traceloop-sdk/traceloop/sdk/utils/json_encoder.py`:
- Around line 18-23: The branch handling hasattr(o, "json") currently only
returns a value when o.json is callable; to preserve existing behavior you must
also handle non-callable json attributes: keep the current callable path (use
json_method = o.json, call it when callable and not inspect.iscoroutinefunction,
and return result if not inspect.iscoroutine(result)), and add an else branch
that returns the non-callable o.json value directly (without calling) so it
doesn't fall through to the class-name fallback; ensure these checks use the
same symbols (hasattr(o, "json"), json_method, inspect.iscoroutinefunction,
inspect.iscoroutine) and place this logic before the fallback that returns the
object's class name.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 316c3afc-d5d3-4e32-8875-d4d79cc263d2
📒 Files selected for processing (2)
packages/traceloop-sdk/tests/test_workflows.pypackages/traceloop-sdk/traceloop/sdk/utils/json_encoder.py
max-deygin-traceloop
left a comment
There was a problem hiding this comment.
If possible, please add a regression test for the sync json() method.
This is minor, we can merge without it.
53babf9 to
625bb89
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/traceloop-sdk/tests/test_workflows.py (1)
511-528: Strengthen regression by asserting no unawaited-coroutine warning.The current assertions validate serialized values, but the original bug was the
RuntimeWarningside effect. Add an explicit warning assertion so this cannot regress silently.Proposed test hardening
`@pytest.mark.asyncio` -async def test_async_workflow_with_async_json_method_argument(exporter): +async def test_async_workflow_with_async_json_method_argument(exporter, recwarn): `@workflow`(name="request_workflow") async def request_workflow(request: FakeAsyncRequest): return {"ok": True} await request_workflow(FakeAsyncRequest()) + assert not any( + w.category is RuntimeWarning and "was never awaited" in str(w.message) + for w in recwarn + ) spans = exporter.get_finished_spans() assert [span.name for span in spans] == ["request_workflow.workflow"]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/traceloop-sdk/tests/test_workflows.py` around lines 511 - 528, Wrap the call to await request_workflow(FakeAsyncRequest()) inside a warnings-capture context and assert no RuntimeWarning was emitted so the regression can't slip by; specifically modify the test_async_workflow_with_async_json_method_argument test to capture warnings (e.g., using warnings.catch_warnings(record=True) or pytest.warns(None) around the await) and then assert that none of the captured warnings have category RuntimeWarning, keeping the rest of the assertions (exporter spans, JSON attributes) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/traceloop-sdk/tests/test_workflows.py`:
- Around line 511-528: Wrap the call to await
request_workflow(FakeAsyncRequest()) inside a warnings-capture context and
assert no RuntimeWarning was emitted so the regression can't slip by;
specifically modify the test_async_workflow_with_async_json_method_argument test
to capture warnings (e.g., using warnings.catch_warnings(record=True) or
pytest.warns(None) around the await) and then assert that none of the captured
warnings have category RuntimeWarning, keeping the rest of the assertions
(exporter spans, JSON attributes) unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f789923d-7462-4c8a-aa33-25620db1c49c
📒 Files selected for processing (1)
packages/traceloop-sdk/tests/test_workflows.py
|
thank you @trinhchien, LGTM, if you don't mind please sign the CLA and we can merge |
901fdae to
213bc97
Compare
Thanks for the heads-up — I found that the issue was caused by using the wrong commit email on my side. I’ve now rewritten the PR commits with the correct GitHub-linked email and pushed the updated branch. Could you please re-check the CLA status? |
| if not inspect.iscoroutine(result): | ||
| return result |
There was a problem hiding this comment.
| if not inspect.iscoroutine(result): | |
| return result | |
| if not inspect.iscoroutine(result): | |
| return result | |
| else: | |
| result.close() |
Also lets verify in tests that no runtime warning is emitted
Summary
.json()methods during input serializationjson()methodWhy
JSONEncodercurrently calls any.json()method it finds synchronously. For objects like Starlette/FastAPIRequest,json()is async, which leads toRuntimeWarning: coroutine ... was never awaitedduring workflow input serialization.Testing
pytest packages/traceloop-sdk/tests/test_workflows.py -q -k 'async_json_method_argument'pytest packages/traceloop-sdk/tests/test_workflows.py -q -k 'dataclass_serialization_workflow or async_json_method_argument'Summary by CodeRabbit
Bug Fixes
Tests