langchain-ai/deepagents · error · ValueError

MCPServerInfo {self.name!r}: pending_reconnect requires stat

Error message

MCPServerInfo {self.name!r}: pending_reconnect requires status='disabled' (got {self.status!r})

What it means

MCPServerInfo.__post_init__ requires that a server flagged pending_reconnect has status exactly 'disabled'. pending_reconnect marks a server awaiting user action; any other status is an inconsistent state the library refuses to construct.

Source

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

        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"


_SUPPORTED_REMOTE_TYPES = {"sse", "http"}
"""Supported transport types for remote MCP servers (SSE and HTTP)."""

_TRANSPORT_ALIASES = {"streamable_http": "http", "streamable-http": "http"}
"""Aliases that normalize to canonical transport names.

The MCP spec and `langchain_mcp_adapters` use `streamable_http` for what the
app calls `http`. Accept both so users copy-pasting from upstream docs don't
hit a validation error.
"""

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Set status='disabled' whenever pending_reconnect=True
  2. Clear pending_reconnect (False) if the server should stay in another status
  3. Reconstruct the object from current live state instead of patching one field

Example fix

// before
MCPServerInfo(name='gh', status='connected', pending_reconnect=True)
// after
MCPServerInfo(name='gh', status='disabled', pending_reconnect=True)
Defensive patterns

Strategy: validation

Validate before calling

assert not (pending_reconnect and status != 'disabled'), 'pending_reconnect requires status=disabled'

Type guard

def is_reconnect_pending(info: MCPServerInfo) -> bool:
    return info.pending_reconnect and info.status == 'disabled'

Try / catch

try:
    info = MCPServerInfo(name=name, status=status, pending_reconnect=pending)
except ValueError as e:
    log.error('inconsistent MCPServerInfo: %s', e)
    raise

Prevention

When it happens

Trigger: Creating MCPServerInfo with pending_reconnect=True and status other than 'disabled' (e.g. 'connected', 'unauthenticated', 'error').

Common situations: State machine code that toggles pending_reconnect after updating status; deserializing persisted server state where status and the reconnect flag drifted apart.

Related errors


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