langchain-ai/deepagents · error · ValueError

MCPServerInfo {self.name!r}: status={self.status!r} requires

Error message

MCPServerInfo {self.name!r}: status={self.status!r} requires an error message

What it means

The counterpart invariant to [358]: any status other than 'ok' (e.g. 'error') must carry an error message explaining the failure, and must not carry tools. Constructing MCPServerInfo with a failure status and error=None fails first with 'requires an error message'; if tools are present it raises 'cannot carry tools'.

Source

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

            ValueError: If any of: `status='ok'` with a non-`None` error;
                non-`ok` status without an error message; non-`ok` status
                carrying tools; or `pending_reconnect` set without
                `status='disabled'`.
        """
        if self.status == "ok":
            if self.error is not None:
                msg = (
                    f"MCPServerInfo {self.name!r}: status='ok' cannot carry "
                    f"an error (got {self.error!r})"
                )
                raise ValueError(msg)
        else:
            if self.error is None:
                msg = (
                    f"MCPServerInfo {self.name!r}: status={self.status!r} "
                    "requires an error message"
                )
                raise ValueError(msg)
            if self.tools:
                msg = (
                    f"MCPServerInfo {self.name!r}: status={self.status!r} "
                    "cannot carry tools"
                )
                raise ValueError(msg)
        if self.pending_reconnect and self.status != "disabled":
            msg = (
                f"MCPServerInfo {self.name!r}: pending_reconnect requires "
                f"status='disabled' (got {self.status!r})"
            )
            raise ValueError(msg)

    def needs_attention(self) -> bool:
        """Return whether this server is blocked on user login."""
        return self.status == "unauthenticated"

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Always attach a descriptive error string when status is not 'ok' (e.g. str(exc) or the connection failure reason).
  2. Pass tools=[] (omit tools) for failure statuses; tools only belong to healthy servers.
  3. Fix exception handlers that swallow the exception message instead of forwarding it.

Example fix

// before
except Exception:
    infos.append(MCPServerInfo(name="notion", status="error", error=None, tools=[]))
// after
except Exception as exc:
    infos.append(MCPServerInfo(name="notion", status="error", error=str(exc), tools=[]))
Defensive patterns

Strategy: type-guard

Validate before calling

def make_failure_info(name: str, exc: Exception) -> MCPServerInfo:
    if not str(exc):
        raise ValueError("failure status requires a non-empty error message")
    return MCPServerInfo(name=name, status="error", error=str(exc), tools=[])

Type guard

def is_valid_failure(info: MCPServerInfo) -> bool:
    return info.status != "ok" and info.error is not None and not info.tools

Try / catch

try:
    info = MCPServerInfo(name=name, status="error", error=None)
except ValueError as exc:
    print(f"fixing failure info: {exc}")
    info = MCPServerInfo(name=name, status="error", error="unknown failure", tools=[])

Prevention

When it happens

Trigger: Constructing `MCPServerInfo(name=..., status='error', error=None)` or `MCPServerInfo(name=..., status='error', error='...', tools=[...])` when aggregating MCP server connection results.

Common situations: Catch blocks that record the failure status but forget to attach the exception text; code paths that optimistically populate tools before discovering the connection failed; test fixtures that omit error details.

Related errors


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