Skip to content

fix: serialize dict/list tool output to JSON (#6267)#6334

Open
C1-BA-B1-F3 wants to merge 2 commits into
crewAIInc:mainfrom
C1-BA-B1-F3:fix/dict-serialize-v3
Open

fix: serialize dict/list tool output to JSON (#6267)#6334
C1-BA-B1-F3 wants to merge 2 commits into
crewAIInc:mainfrom
C1-BA-B1-F3:fix/dict-serialize-v3

Conversation

@C1-BA-B1-F3

@C1-BA-B1-F3 C1-BA-B1-F3 commented Jun 25, 2026

Copy link
Copy Markdown

Fixes #6267

Summary

  • When a tool returns a dict or list, str() produces Python repr (e.g. {'key': 'value'}) instead of valid JSON. This causes parsing issues for agents expecting JSON.
  • The fix checks isinstance(raw_result, (dict, list)) and uses json.dumps() in both fallback paths of _format_tool_output_for_agent.

Changes

  • lib/crewai/src/crewai/tools/structured_tool.py: In _format_tool_output_for_agent, use json.dumps(raw_result) instead of str(raw_result) when raw_result is a dict or list (both in the no-schema early return and the validation-failure except fallback).

Summary by CodeRabbit

  • Bug Fixes
    • Structured tool outputs are now returned as JSON when the result is a list or dictionary, making responses more consistent and easier to consume.
    • Fallback behavior now preserves structured data more reliably when output validation or serialization issues occur.

@corridor-security corridor-security Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary: This PR changes tool-output formatting to serialize dict/list results as JSON in fallback paths.

Risk: Low risk. The change affects internal result serialization and does not introduce new authentication, authorization, data access, command execution, SQL, filesystem, or network attack surfaces; no exploitable security vulnerabilities were identified.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c31f1005-cd6b-45c8-9a86-048710567fa5

📥 Commits

Reviewing files that changed from the base of the PR and between 933b215 and 27dd283.

📒 Files selected for processing (1)
  • lib/crewai/src/crewai/tools/structured_tool.py

📝 Walkthrough

Walkthrough

_format_tool_output_for_agent now JSON-serializes dict and list tool results in both fallback paths instead of converting them with str().

Changes

Structured tool output formatting

Layer / File(s) Summary
Fallback JSON serialization
lib/crewai/src/crewai/tools/structured_tool.py
Both fallback branches in _format_tool_output_for_agent now call json.dumps() for dict and list results and keep str() for other values.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main fix: serializing dict/list tool output to JSON for issue #6267.
Linked Issues check ✅ Passed The code now JSON-serializes dict/list tool outputs in both fallback paths, addressing the nested-dict crash described in #6267.
Out of Scope Changes check ✅ Passed The changes are narrowly scoped to the tool output formatter and align with the linked issue objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/crewai/src/crewai/tools/structured_tool.py (1)

75-87: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Warning message no longer matches fallback behavior.

The warning says it falls back to str(raw_result), but for dict/list it now falls back to JSON serialization. This is misleading during debugging.

Proposed fix
-                "Falling back to str(raw_result)."
+                "Falling back to JSON for dict/list, otherwise str(raw_result)."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/tools/structured_tool.py` around lines 75 - 87, The
warning in StructuredTool’s fallback path is misleading because it always says
“Falling back to str(raw_result)” even though dict/list values are serialized
with json.dumps first. Update the warning text in structured_tool.py’s fallback
block to accurately describe the actual behavior, referencing the structured
tool result handling around the warning and the isinstance(raw_result, (dict,
list)) branch so the message matches the returned value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/crewai/src/crewai/tools/structured_tool.py`:
- Around line 61-63: The fallback in structured_tool’s result formatting still
assumes dict/list values are JSON-serializable, so it can raise TypeError inside
the safe path. Update the logic around the raw_result handling in
structured_tool.py (and the same fallback near the other referenced block) to
use a serialization-safe approach or a guarded json.dumps call that cannot crash
on nested non-JSON-native objects, while preserving the existing dict/list vs.
scalar behavior.

---

Outside diff comments:
In `@lib/crewai/src/crewai/tools/structured_tool.py`:
- Around line 75-87: The warning in StructuredTool’s fallback path is misleading
because it always says “Falling back to str(raw_result)” even though dict/list
values are serialized with json.dumps first. Update the warning text in
structured_tool.py’s fallback block to accurately describe the actual behavior,
referencing the structured tool result handling around the warning and the
isinstance(raw_result, (dict, list)) branch so the message matches the returned
value.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ac6983f-ece5-4a44-ac08-fc562e42a367

📥 Commits

Reviewing files that changed from the base of the PR and between 01fc389 and 933b215.

📒 Files selected for processing (1)
  • lib/crewai/src/crewai/tools/structured_tool.py

Comment thread lib/crewai/src/crewai/tools/structured_tool.py
- Add default=str to json.dumps calls to handle non-JSON-serializable objects
- Update warning message to accurately describe fallback behavior (JSON for dict/list, otherwise str)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]Agent execution loop crashes with TypeError when custom tool returns a nested dict

1 participant