[BUG]: ensure_type_in_schemas incorrectly forces empty schemas {} to {"type": "object"} in anyOf/oneOf
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
Research direction
Start with lib/crewai/src/crewai/utilities/pydantic_schema_utils.py and inspect ensure_type_in_schemas() around the empty-schema handling described in the issue. Trace how that function handles anyOf and oneOf, then check existing tests for these schemas. Done means {} retains its unconstrained JSON Schema meaning while the intended strict-mode behavior is preserved.
Written by the indexing model from the issue text.
Description
Description
In lib/crewai/src/crewai/utilities/pydantic_schema_utils.py, ensure_type_in_schemas() converts empty schemas {} inside anyOf / oneOf into {"type": "object"}:
# lib/crewai/src/crewai/utilities/pydantic_schema_utils.py (lines 290-292)
for i, schema in enumerate(schema_list):
if isinstance(schema, dict) and schema == {}:
schema_list[i] = {"type": "object"}
In JSON Schema specification, {} represents an unconstrained schema (accepting any value, including primitives such as strings, numbers, and booleans). Converting {} to {"type": "object"} corrupts schema semantics:
- When a tool has a parameter typed as
AnyorOptional[Any], Pydantic generates{"anyOf": [{}, {"type": "null"}]}. ensure_type_in_schemastransforms this into{"anyOf": [{"type": "object"}, {"type": "null"}]}.- As a result, the tool parameter is restricted to dictionaries/objects only. If an LLM returns a valid scalar (e.g.
42or"ok"), validation fails or the LLM is forced to return{}instead of the requested scalar.
Steps to Reproduce
from copy import deepcopy
from crewai.utilities.pydantic_schema_utils import ensure_type_in_schemas
schema = {"anyOf": [{}, {"type": "null"}]}
result = ensure_type_in_schemas(deepcopy(schema))
print(result)
# Observed:
# {'anyOf': [{'type': 'object'}, {'type': 'null'}]}
Expected Behavior
Empty schemas {} (representing Any) should not be unconditionally converted to {"type": "object"}. If OpenAI strict mode requires an explicit type, converting {} to an object restricts valid scalar arguments. The conversion should either preserve {} when not enforcing strict object constraints or avoid coercing unconstrained types to object.
Additional Context
- Python environment: Python 3.10+ / Pydantic v2
- File:
lib/crewai/src/crewai/utilities/pydantic_schema_utils.py
- Dominant language
- Python
- Stars
- 59.8k
- Forks
- 8.8k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 90
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing 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.
More from crewAIInc/crewAI
-
[BUG] Restore Flow.chat() configuration when trace finalization failsPossibly taken @MouryB claimed this 6 days ago. Openbug difficulty:easy good first issue help wanted llm-generated
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
crewAIInc/crewAI#8069 · 1 comment ·
Maintainers usually reply within 1 day
-
[BUG] Callable guardrails fail when event metadata cannot inspect their sourcePossibly taken @xiajiahang claimed this 7 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
crewAIInc/crewAI#8056 · 1 comment ·
Maintainers usually reply within 1 day
-
[BUG] MCPClient silently drops empty [] and {} tool arguments (and list items that clean to empty) before they reach the MCP serverPossibly taken @Hugo-DDT claimed this 7 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
[BUG] Qdrant RAG client applies score_threshold to raw cosine similarity, not the 0-1 score it returnsPossibly taken @roydonsequeira claimed this 9 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
[FEATURE] Add --list to crewai replay for discovering replayable tasksPossibly taken @jiangjiang248 claimed this 9 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
All issues in crewAIInc/crewAI
Similar issues
-
documentation good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
drevendev/HungryCrab#273 ·
Maintainers usually reply within 1 day
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
drevendev/BeautifulRepo#19 ·
Maintainers usually reply within 2 days
-
Moonshot: Kimi K3 always sends `reasoning_effort="max"`, though the API now accepts `low` and `high`Openaccepted
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
UKGovernmentBEIS/inspect_ai#5939 ·
Maintainers usually reply within 1 day
-
bug linux
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
area:data data-quality
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
reacher-z/Awesome-CUA#1468 ·
Maintainers usually reply within 1 day