HKUDS/DeepTutor · error · HTTPException
{exc}
Error message
{exc} What it means
Raised by PUT '' (update_mcp_settings) when constructing MCPConfig(servers=payload.servers) raises a Pydantic ValidationError or ValueError — i.e. the submitted server configuration fails model-level validation (wrong field types, unknown/invalid enum values, malformed structure) before semantic checks run. Returns 400 with the exception's message.
Source
Thrown at deeptutor/api/routers/mcp_settings.py:73
@router.get("")
async def get_mcp_settings() -> dict[str, Any]:
config = load_mcp_config()
manager = get_mcp_manager()
await manager.ensure_started()
return {
"servers": {name: cfg.model_dump(mode="json") for name, cfg in config.servers.items()},
"status": manager.status(),
}
@router.put("")
async def update_mcp_settings(payload: MCPSettingsPayload) -> dict[str, Any]:
try:
config = MCPConfig(servers=payload.servers)
except (ValidationError, ValueError) as exc:
raise HTTPException(status_code=400, detail=str(exc))
_validate_servers(config)
save_mcp_config(config)
manager = get_mcp_manager()
await manager.reload()
return {"status": manager.status()}
@router.put("/servers/{name}")
async def upsert_mcp_server(name: str, cfg: MCPServerConfig) -> dict[str, Any]:
"""Upsert one server, leaving every other entry byte-identical.
The whole-map ``PUT`` above cannot express "change this one": a client has to
send back everything it read, so it silently drops any field it does not
model (a hand-written ``disabled_tools`` blocklist) and overwrites whatever
a second administrator saved in between.
"""
config = load_mcp_config()
servers = dict(config.servers)View on GitHub (pinned to 3e82f13042)
Solutions
- Read the detail message — Pydantic errors name the exact field and expected type
- Fix the offending field type per the MCPServerConfig schema (args: list[str], env: dict, etc.)
- Validate the payload against the documented schema (or fetch GET the current settings and mirror its shape) before PUTting
- After upgrading deeptutor, re-check the settings schema for renamed/retyped fields
Example fix
// before
{"servers": {"fs": {"command": "npx", "args": "-y server-fs /tmp"}}}
// after
{"servers": {"fs": {"command": "npx", "args": ["-y", "server-fs", "/tmp"]}}} Defensive patterns
Strategy: validation
Validate before calling
const res = await api.get('/mcp');
const validShape = res.servers; // mirror this structure
// validate types before PUT
for (const cfg of Object.values(newServers)) {
if (cfg.args && !Array.isArray(cfg.args)) throw new Error('args must be an array');
if (cfg.env && typeof cfg.env !== 'object') throw new Error('env must be an object');
} Type guard
function isMCPServerConfig(v: unknown): v is MCPServerConfig {
const c = v as Record<string, unknown>;
return typeof c === 'object' && c !== null &&
(c.command === undefined || typeof c.command === 'string') &&
(c.args === undefined || Array.isArray(c.args)) &&
(c.env === undefined || typeof c.env === 'object');
} Try / catch
try {
await api.put('/mcp', { servers });
} catch (e) {
if (e.status === 400) {
// e.detail contains the Pydantic message naming the bad field — fix and retry
}
} Prevention
- Derive the payload from GET /mcp output rather than hand-writing it
- Run client-side type checks mirroring the Pydantic schema
- Re-check the schema after deeptutor upgrades
When it happens
Trigger: PUT the MCP settings endpoint with a payload whose servers values violate MCPServerConfig field types, e.g. args as a string instead of a list, env as a list instead of a dict, or numeric values where strings are required.
Common situations: Hand-writing the settings JSON from memory instead of copying the schema; a frontend form serializing types incorrectly; API docs out of date with the current Pydantic model after an upgrade changed field types.
Related errors
- mcp.configure_command_or_url
- mcp.server_error
- mcp.configure_before_testing
- Unsupported import source: {value!r}
- No records provided
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/af2d045c4c5268aa.
Report an issue: GitHub.