langchain-ai/deepagents · error · TypeError
{prefix}.{name} must be a dictionary, got {type(values).__na
Error message
{prefix}.{name} must be a dictionary, got {type(values).__name__} What it means
resolve_mcp_server_env validates the resolved `env` and `headers` fields of an MCP server config before resolving templated values. If either field resolves to anything other than a dictionary (e.g. a list, string, or null), this TypeError is thrown. The library enforces the MCP config schema: env/headers must be string-keyed mappings.
Source
Thrown at libs/code/deepagents_code/mcp_config.py:173
resolved[name] = _resolve_string(resolved[name], field=f"{prefix}.{name}")
if "args" in resolved:
args = resolved["args"]
if not isinstance(args, list):
msg = f"{prefix}.args must be a list, got {type(args).__name__}"
raise TypeError(msg)
resolved["args"] = [
_resolve_string(value, field=f"{prefix}.args[{index}]")
for index, value in enumerate(args)
]
for name in ("env", "headers"):
if name not in resolved:
continue
values = resolved[name]
if not isinstance(values, dict):
msg = f"{prefix}.{name} must be a dictionary, got {type(values).__name__}"
raise TypeError(msg)
resolved[name] = _resolve_mapping_values(values, field=f"{prefix}.{name}")
return resolved
View on GitHub (pinned to a1af029e6e)
Solutions
- Fix the server config so `env` and `headers` are mappings of string keys to string values (e.g. `env: {API_KEY: 'x'}` not `env: ['API_KEY=x']`).
- Check for null: a key with no value (`headers:` with nothing after it) resolves to None; give it at least `{}`.
- If configs are merged from multiple sources, verify the winning layer defines these fields as dictionaries.
- Run `dcode mcp login list` / the test entrypoint to validate the config before reconnecting.
Example fix
# before (config) env: - API_KEY=secret # after env: API_KEY: secret
Defensive patterns
Strategy: type-guard
Validate before calling
for field in ("env", "headers"):
value = server_config.get(field, {})
if not isinstance(value, dict):
raise TypeError(f"{server_name}.{field} must be a dictionary, got {type(value).__name__}") Type guard
def is_str_mapping(value: object) -> TypeGuard[dict[str, str]]:
return isinstance(value, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in value.items()) Try / catch
try:
env = resolve_mcp_server_env(server)
except TypeError as exc:
print(f"Bad MCP config for {server_name}: {exc}; fix env/headers to be mappings") Prevention
- Define env/headers as key: value mappings, never lists of KEY=VALUE strings
- Avoid bare keys with no value; use explicit empty mappings {}
- Lint mcp config files (TOML/YAML) before committing
When it happens
Trigger: Calling resolve_mcp_server_env (directly or via run_mcp_login_list, resolve_headers, login, or _preflight_and_connect) with an MCP server config where `env` or `headers` is a list, string, or other non-dict value after config resolution.
Common situations: A typo'd YAML/TOML config that defines `env` as a list of `KEY=VALUE` strings instead of a mapping; a project-level mcp.json with `headers: []`; merging configs that replace the dict with null; hand-editing config files with wrong indentation.
Related errors
- Server '{server_name}' '{field_name}' must be a list of stri
- 'mcpServers' field must be a dictionary
- -32002
- MCP config file not found: {mcp_config_path}
- Invalid MCP config at {mcp_config_path}: {exc}
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/be2c6bdc1d23adb9.
Report an issue: GitHub.