BerriAI/litellm · error · ValueError
defer_loading must be a boolean
Error message
defer_loading must be a boolean
What it means
While mapping optional tool attributes, LiteLLM found a top-level 'defer_loading' key on a tool that supports it (i.e. not a tool-search or computer tool) but its value is not a Python bool. The value is type-checked strictly, so strings like 'true' or 1/0 are rejected with this ValueError.
Source
Thrown at litellm/llms/anthropic/chat/transformation.py:802
returned_tool["cache_control"] = _cache_control
elif _cache_control_function is not None and isinstance(_cache_control_function, dict):
returned_tool["cache_control"] = ChatCompletionCachedContent(**_cache_control_function)
## check if defer_loading is set in the tool
_defer_loading: Final = tool.get("defer_loading", None)
_defer_loading_function: Final = tool.get("function", {}).get("defer_loading", None)
if returned_tool is not None:
# Only set defer_loading on tools that support it (not tool search tools or computer tools)
tool_type = returned_tool.get("type", "")
if tool_type not in (
"tool_search_tool_regex_20251119",
"tool_search_tool_bm25_20251119",
"computer_20241022",
"computer_20250124",
):
if _defer_loading is not None:
if not isinstance(_defer_loading, bool):
raise ValueError("defer_loading must be a boolean")
returned_tool["defer_loading"] = _defer_loading
elif _defer_loading_function is not None:
if not isinstance(_defer_loading_function, bool):
raise ValueError("defer_loading must be a boolean")
returned_tool["defer_loading"] = _defer_loading_function
## check if allowed_callers is set in the tool
_allowed_callers: Final = tool.get("allowed_callers", None)
_allowed_callers_function: Final = tool.get("function", {}).get("allowed_callers", None)
if returned_tool is not None:
# Only set allowed_callers on tools that support it (not tool search tools or computer tools)
tool_type = returned_tool.get("type", "")
if tool_type not in (
"tool_search_tool_regex_20251119",
"tool_search_tool_bm25_20251119",
"computer_20241022",
"computer_20250124",
):View on GitHub (pinned to 6c2dcb801b)
Solutions
- Use a real boolean: defer_loading: true (unquoted) in YAML, or true in JSON.
- If the value comes from config/env, coerce before building the tool: bool parsing like value in ('true', '1', True).
- Note defer_loading may also live under 'function' (that path is checked only when the top-level key is absent).
Example fix
# before (YAML/config) "defer_loading": "true" # string -> ValueError # after "defer_loading": True # actual boolean
Defensive patterns
Strategy: validation
Validate before calling
for t in tools:
if "defer_loading" in t and not isinstance(t["defer_loading"], bool):
t["defer_loading"] = str(t["defer_loading"]).lower() in ("true", "1") Type guard
def defer_loading_ok(tool) -> bool:
v = tool.get("defer_loading")
return v is None or isinstance(v, bool) Prevention
- In YAML write defer_loading: true unquoted.
- Run a coercion pass over config-loaded tool dicts before calling LiteLLM.
When it happens
Trigger: Passing {'type': 'custom', ..., 'defer_loading': 'true'} or defer_loading: 1 in a tool dict; values loaded from YAML/JSON config where booleans arrive as strings ('true'/'false') or ints.
Common situations: YAML configs parsed without bool coercion (only literal true/false become bool; quoted 'true' stays a string); JSON produced by another service that serializes booleans as 0/1; env-var-driven flags injected as strings.
Related errors
- allowed_callers must be a list of strings
- Missing required parameter: parameters
- Missing required parameter: display_width_px or display_heig
- Missing required parameter: name
- Tool search tool must have a valid name
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/71b2eaa4719ddd19.
Report an issue: GitHub.