microsoft/autogen · error · ValueError
json_output must be a boolean, a BaseModel subclass or None.
Error message
json_output must be a boolean, a BaseModel subclass or None.
What it means
In create(), json_output is validated to be exactly True/False, None, or a BaseModel subclass. Anything else (an int, a string, a BaseModel *instance* instead of the class, a dataclass) hits the elif chain's final raise. Note the message text omits the instance case, but passing an instance is the most common way to land here because isinstance(json_output, type) is False for instances.
Source
Thrown at python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/_llama_cpp_completion_client.py:305
if isinstance(msg, SystemMessage):
converted_messages.append({"role": "system", "content": msg.content})
elif isinstance(msg, UserMessage) and isinstance(msg.content, str):
converted_messages.append({"role": "user", "content": msg.content})
elif isinstance(msg, AssistantMessage) and isinstance(msg.content, str):
converted_messages.append({"role": "assistant", "content": msg.content})
elif (
isinstance(msg, SystemMessage) or isinstance(msg, UserMessage) or isinstance(msg, AssistantMessage)
) and isinstance(msg.content, list):
raise ValueError("Multi-part messages such as those containing images are currently not supported.")
else:
raise ValueError(f"Unsupported message type: {type(msg)}")
if isinstance(json_output, type) and issubclass(json_output, BaseModel):
create_args["response_format"] = {"type": "json_object", "schema": json_output.model_json_schema()}
elif json_output is True:
create_args["response_format"] = {"type": "json_object"}
elif json_output is not False and json_output is not None:
raise ValueError("json_output must be a boolean, a BaseModel subclass or None.")
# Handle tool_choice parameter
if tool_choice != "auto":
warnings.warn(
"tool_choice parameter is specified but LlamaCppChatCompletionClient does not support it. "
"This parameter will be ignored.",
UserWarning,
stacklevel=2,
)
if self.model_info["function_calling"]:
# Run this in on the event loop to avoid blocking.
response_future = asyncio.get_event_loop().run_in_executor(
None,
lambda: self.llm.create_chat_completion(
messages=converted_messages, tools=convert_tools(tools), stream=False, **create_args
),
)View on GitHub (pinned to 027ecf0a37)
Solutions
- Pass the class, not an instance: json_output=MyModel (no parentheses)
- Pass json_output=True for plain JSON mode, False or None to disable
- If json_output comes from config, coerce it first: json_output = {'true': True, 'false': False}.get(str(cfg).lower(), cfg)
Example fix
# before result = await client.create(messages, json_output=StepPlan()) # instance -> ValueError # after result = await client.create(messages, json_output=StepPlan) # the class itself
Defensive patterns
Strategy: type-guard
Validate before calling
from pydantic import BaseModel
def coerce_json_output(v: object) -> bool | type[BaseModel] | None:
if v is None or isinstance(v, bool):
return v
if isinstance(v, type) and issubclass(v, BaseModel):
return v
if isinstance(v, str) and v.lower() in ("true", "false"):
return v.lower() == "true"
raise TypeError(f"json_output cannot be {type(v)!r}")
result = await client.create(messages, json_output=coerce_json_output(cfg["json_output"])) Type guard
def is_valid_json_output(v: object) -> TypeGuard[bool | type[BaseModel] | None]:
return v is None or isinstance(v, bool) or (isinstance(v, type) and issubclass(v, BaseModel)) Try / catch
try:
result = await client.create(messages, json_output=jo)
except ValueError as e:
if "json_output must be" in str(e):
result = await client.create(messages, json_output=bool(jo))
else:
raise Prevention
- Always pass the BaseModel class, never an instance
- Type your wrappers' json_output as Optional[bool | type[BaseModel]] so mypy/pyright catch misuse
- Parse config booleans into real bools before forwarding
When it happens
Trigger: create(messages, json_output=MyModel()) — instance instead of class; json_output=1 or json_output='json'; passing a pydantic dataclass or TypedDict class; forwarding an unvalidated config value into json_output.
Common situations: Dynamically deserializing config (YAML/JSON) where json_output arrives as the string 'true'; passing a schema instance built elsewhere; copy-paste from code that used a different client whose API takes an instance.
Related errors
- json_output must be a boolean or a Pydantic model class, got
- tool_choice specified but no tools provided
- response_format must be a Pydantic model class, not {type(va
- Failed to list MCP prompts
- Failed to get MCP prompt
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/d9cbae7f007031fd.
Report an issue: GitHub.