langchain-ai/deepagents · error · TypeError
Server '{server_name}' 'headers' must be a dictionary
Error message
Server '{server_name}' 'headers' must be a dictionary What it means
MCP server configs of type http/sse accept an optional `headers` dict sent with each request to the remote server. This TypeError is raised by `_validate_server_config` when `headers` is present but is not a dictionary (e.g. a list, string, or null-like non-dict value), preventing an invalid type from reaching the transport layer.
Source
Thrown at libs/code/deepagents_code/mcp_tools.py:898
if "url" not in server_config:
error_msg = (
f"Server '{server_name}' with type '{server_type}' "
"missing required 'url' field"
)
raise ValueError(error_msg)
if "command" in server_config:
error_msg = (
f"Server '{server_name}' has type '{server_type}' (remote) "
"but also declares a 'command' field. Remove 'command' or "
'set `"type": "stdio"`.'
)
raise ValueError(error_msg)
headers = server_config.get("headers")
if headers is not None and not isinstance(headers, dict):
error_msg = f"Server '{server_name}' 'headers' must be a dictionary"
raise TypeError(error_msg)
if isinstance(headers, dict):
for name, value in headers.items():
if not isinstance(value, str):
error_msg = (
f"Server '{server_name}' header {name!r} must be "
f"a string, got {type(value).__name__}"
)
raise TypeError(error_msg)
elif server_type == "stdio":
if "command" not in server_config:
error_msg = f"Server '{server_name}' missing required 'command' field"
raise ValueError(error_msg)
if "url" in server_config:
error_msg = (
f"Server '{server_name}' has type 'stdio' but also declares "
"a 'url' field. Remove 'url' or set "View on GitHub (pinned to a1af029e6e)
Solutions
- Change `headers` in the server config to a dictionary mapping header names to string values, e.g. {"Authorization": "Bearer <token>"}.
- If headers were written as a list of 'Name: value' strings, split each on the first colon and build a dict.
- Remove the `headers` key entirely if no custom headers are needed (it is optional).
- Run the config through `resolve_and_load_mcp_tools` on a small test config to validate before deploying.
Example fix
// before
{"servers": {"docs": {"type": "http", "url": "https://mcp.example.com", "headers": ["Authorization: Bearer tok"]}}}
// after
{"servers": {"docs": {"type": "http", "url": "https://mcp.example.com", "headers": {"Authorization": "Bearer tok"}}}} Defensive patterns
Strategy: validation
Validate before calling
def validate_server_entry(name: str, cfg: dict) -> None:
if cfg.get("type", "stdio") in ("http", "sse"):
headers = cfg.get("headers")
if headers is not None and not isinstance(headers, dict):
raise TypeError(f"Server '{name}' 'headers' must be a dictionary, got {type(headers).__name__}") Type guard
def has_dict_headers(cfg: dict) -> bool:
h = cfg.get("headers")
return h is None or isinstance(h, dict) Prevention
- Always author headers as a JSON/YAML object mapping name to string value, never as a list of 'Name: value' strings.
- Run `resolve_and_load_mcp_tools` (or the app's /mcp command) against a draft config before committing it.
- Keep one canonical server-config schema documented and validated in CI.
- Enable config loading errors visibly instead of ignoring dropped servers.
When it happens
Trigger: Calling `select_server`, `resolve_and_load_mcp_tools`, or config validation entry points (`_validate_mcp_config_servers`, `_drop_invalid_mcp_config_servers`) with a server entry of type `http`/`sse` whose `headers` key is set to a non-dict value, e.g. `"headers": ["Authorization: Bearer x"]` or `"headers": "Authorization: ..."`.
Common situations: Config copied from curl examples where headers are written as a list of strings; YAML/JSON authored by hand with headers as an array; merging header snippets incorrectly; a stringified headers block pasted from documentation.
Related errors
- Server '{server_name}' header {name!r} must be a string, got
- Server '{server_name}' 'args' must be a list
- Server '{server_name}' 'env' must be a dictionary
- {str(exc)}
- {field} references unset env var {name}. Set {name} in the e
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/36be9a491ef41a55.
Report an issue: GitHub.