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
- Always attach a descriptive error string when status is not 'ok' (e.g. str(exc) or the connection failure reason).
- Pass tools=[] (omit tools) for failure statuses; tools only belong to healthy servers.
- 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
- Always forward the exception text into `error` in except blocks (use `except ... as exc`)
- Never populate `tools` when the connection failed
- Use a single factory for building failure MCPServerInfo entries
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
- MCPServerInfo {self.name!r}: status='ok' cannot carry an err
- ConfigResolution must have at least one used path
- {self.scope} MCP config {need} a project root: {self.path}
- ColdCacheWarning age_seconds={self.age_seconds!r} does not p
- `unreadable_reason` implies the token is not usable; `logged
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/adb1eb91b4da560a.
Report an issue: GitHub.