langchain-ai/deepagents · error · TypeError

Server '{server_name}' header {name!r} must be a string, got

Error message

Server '{server_name}' header {name!r} must be a string, got {type(value).__name__}

What it means

HTTP header values sent to remote MCP servers must be strings. `_validate_server_config` iterates each `headers` entry for http/sse servers and raises this TypeError when any value is a non-string (int, dict, list, bool, None, etc.), since HTTP headers are serialized as text and cannot carry structured values.

Source

Thrown at libs/code/deepagents_code/mcp_tools.py:907

                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 "
                '`"type": "http"` (or `"sse"`) for a remote server.'
            )
            raise ValueError(error_msg)

        if "args" in server_config and not isinstance(server_config["args"], list):
            error_msg = f"Server '{server_name}' 'args' must be a list"
            raise TypeError(error_msg)

        if "env" in server_config and not isinstance(server_config["env"], dict):

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Convert each header value to a string, e.g. {"X-Retries": "3"} instead of 3.
  2. Quote values in YAML config files so the parser keeps them as strings.
  3. Remove non-string values and pass such data via `env` (stdio) or query parameters instead.
  4. Wrap potentially non-string values with str(...) when building headers programmatically.

Example fix

// before
"headers": {"X-Retries": 3, "Authorization": token_or_none}
// after
"headers": {"X-Retries": "3", "Authorization": str(token_or_none or "")}
Defensive patterns

Strategy: type-guard

Validate before calling

def validate_header_values(name: str, cfg: dict) -> None:
    headers = cfg.get("headers")
    if isinstance(headers, dict):
        for k, v in headers.items():
            if not isinstance(v, str):
                raise TypeError(f"Server '{name}' header {k!r} must be a string, got {type(v).__name__}")

Type guard

def has_string_headers(cfg: dict) -> bool:
    h = cfg.get("headers")
    return h is None or (isinstance(h, dict) and all(isinstance(v, str) for v in h.values()))

Try / catch

try:
    tools = resolve_and_load_mcp_tools(config)
except TypeError as e:
    if "must be a string" in str(e):
        server_cfg = config["servers"][extract_server_name(str(e))]
        server_cfg["headers"] = {k: str(v) for k, v in server_cfg.get("headers", {}).items()}
        tools = resolve_and_load_mcp_tools(config)
    else:
        raise

Prevention

When it happens

Trigger: A server entry of type `http`/`sse` has `headers` as a dict but at least one value is not a string, e.g. `{"X-Retries": 3}` or `{"X-Debug": true}`, validated via `select_server`, `resolve_and_load_mcp_tools`, or the batch validators.

Common situations: Numeric header values like port or version numbers written unquoted in YAML (YAML auto-types `3` as int); boolean flags as header values; JSON where a token was accidentally nested as an object; templated headers that resolved to None.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/983adfdffda602ea. Report an issue: GitHub.