HKUDS/DeepTutor · error · ValueError
Capability config must be an object.
Error message
Capability config must be an object.
What it means
_clean_public_config rejects a request-level capability config that is not a JSON object/dict. Configs arriving as lists, strings, numbers, or booleans (anything non-None non-dict) raise this ValueError before Pydantic validation runs.
Source
Thrown at deeptutor/runtime/request_contracts.py:78
"chartjs",
"mermaid",
"html",
"manim_video",
"manim_image",
] = "auto"
# Only meaningful when the routed render_type is manim_video / manim_image
# (either chosen explicitly or selected by AnalysisAgent in auto mode).
# Mirrors MathAnimatorRequestConfig defaults so the auto path stays
# zero-config.
quality: Literal["low", "medium", "high"] = "medium"
style_hint: str = Field(default="", max_length=500)
def _clean_public_config(raw_config: dict[str, Any] | None) -> dict[str, Any]:
if raw_config is None:
return {}
if not isinstance(raw_config, dict):
raise ValueError("Capability config must be an object.")
cleaned = dict(raw_config)
for key in _RUNTIME_ONLY_KEYS:
cleaned.pop(key, None)
return cleaned
def _validate_model(
model_type: type[BaseModel],
raw_config: dict[str, Any] | None,
*,
label: str,
) -> BaseModel:
cleaned = _clean_public_config(raw_config)
try:
return model_type.model_validate(cleaned)
except ValidationError as exc:
details = "; ".join(
f"{'.'.join(str(part) for part in error['loc'])}: {error['msg']}"View on GitHub (pinned to 3e82f13042)
Solutions
- Make the request's config field a JSON object, e.g. {"config": {"render_mode": "svg"}}
- If config is double-encoded JSON, parse it once before sending
- Omit config entirely (null is accepted and treated as {}) when you have no config
Example fix
# before
{"config": "{\"render_mode\": \"svg\"}"}
# after
{"config": {"render_mode": "svg"}} Defensive patterns
Strategy: type-guard
Validate before calling
if config is not None and not isinstance(config, dict):
raise TypeError("config must be an object or null")
# or if it might be a JSON string:
import json
if isinstance(config, str):
config = json.loads(config) Type guard
def is_valid_config_shape(cfg: object) -> bool:
return cfg is None or isinstance(cfg, dict) Try / catch
try:
validate_chat_request_config(cfg)
except ValueError as e:
if "must be an object" in str(e):
cfg = {} # or re-shape client payload
result = validate_chat_request_config(cfg) Prevention
- Always build request payloads with dict literals for config
- Never double-encode JSON strings
- Add client-side schema checks (e.g. zod/pydantic) mirroring the server contract
When it happens
Trigger: Sending a chat/deep_solve/deep_question/visualize request (via WebSocket API or SDK) with `config` set to e.g. a JSON array, a bare string, or a number instead of an object.
Common situations: Frontend sending JSON where config is double-encoded (a JSON string containing JSON); clients constructing the payload with the wrong shape; SDK users passing a list of options instead of a dict; copy-paste errors from YAML configs pasted as strings.
Related errors
- Invalid {label} config: {details}
- PageIndex API key is not configured. Add it under Knowledge
- No records provided
- mcp.configure_command_or_url
- mcp.server_error
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/a436be3eae6b592d.
Report an issue: GitHub.