langchain-ai/deepagents · error · TypeError
'mcpServers' field must be a dictionary
Error message
'mcpServers' field must be a dictionary
What it means
The config contains an `mcpServers` key, but `_validate_mcp_config_top_level` additionally requires it to be a dictionary mapping server names to server config objects. If the value is any other JSON type (string, array, number, null) this TypeError is raised.
Source
Thrown at libs/code/deepagents_code/mcp_tools.py:1171
"""Validate top-level MCP configuration fields.
Args:
config: Parsed MCP config dictionary.
Raises:
TypeError: If top-level fields have wrong types.
ValueError: If required top-level fields are missing.
"""
if "mcpServers" not in config:
error_msg = (
"MCP config must contain 'mcpServers' field. "
'Expected format: {"mcpServers": {"server-name": {...}}}'
)
raise ValueError(error_msg)
if not isinstance(config["mcpServers"], dict):
error_msg = "'mcpServers' field must be a dictionary"
raise TypeError(error_msg)
if not config["mcpServers"]:
error_msg = "'mcpServers' field is empty - no servers configured"
raise ValueError(error_msg)
def _validate_mcp_config_servers(config: dict[str, Any]) -> None:
"""Validate every server in an MCP configuration.
Args:
config: Parsed MCP config dictionary.
"""
for server_name, server_config in config["mcpServers"].items():
_validate_server_config(server_name, server_config)
def _drop_invalid_mcp_config_servers(
config: dict[str, Any],View on GitHub (pinned to a1af029e6e)
Solutions
- Convert the value to an object keyed by server name: {"mcpServers": {"fs": {"command": "mcp-server-fs"}}}.
- If the value is a JSON array of server objects, index each one by its name field when rebuilding the object.
- Replace null/placeholder values with a real server map or an empty object (then add servers).
Example fix
// before
{"mcpServers": [{"name": "fs", "command": "mcp-server-fs"}]}
// after
{"mcpServers": {"fs": {"command": "mcp-server-fs"}}} Defensive patterns
Strategy: type-guard
Validate before calling
cfg = json.load(open(path))
servers = cfg.get("mcpServers")
if not isinstance(servers, dict):
raise SystemExit("'mcpServers' must be an object keyed by server name") Type guard
def is_server_map(cfg: object) -> bool:
return isinstance(cfg, dict) and isinstance(cfg.get("mcpServers"), dict) Try / catch
try:
load_mcp_config(path)
except TypeError as e:
if "'mcpServers' field must be a dictionary" in str(e):
convert_list_to_map(path)
else:
raise Prevention
- Key servers by name in the JSON object; don't use arrays of {name, ...} objects.
- Add a JSON schema check (type: object) for mcpServers in CI.
- Be careful when scripts rewrite the config — confirm they preserve the dict shape.
When it happens
Trigger: Config like {"mcpServers": ["fs", "git"]} (list of names), {"mcpServers": "fs"} (string), or {"mcpServers": null}; also files where the servers were written as an array of objects instead of a keyed object.
Common situations: Converting a list of servers from another tool without converting to a keyed object; a script that overwrote mcpServers with a serialized string; template placeholders left as null.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Server '{server_name}' '{field_name}' must be a list of stri
- Invalid MCP config at {mcp_config_path}: {exc}
- {prefix}.{name} must be a dictionary, got {type(values).__na
- Server '{server_name}' cannot set both 'allowedTools' and 'd
- Server '{server_name}' '{field_name}' must be non-empty; omi
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/056a2da087b80476.
Report an issue: GitHub.