{"record":{"id":"adb1eb91b4da560a","repo":"langchain-ai/deepagents","slug":"mcpserverinfo-self-name-r-status-self-status-r","errorCode":null,"errorMessage":"MCPServerInfo {self.name!r}: status={self.status!r} requires an error message","messagePattern":"MCPServerInfo (.+?): status=(.+?) requires an error message","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/mcp_tools.py","lineNumber":185,"sourceCode":"            ValueError: If any of: `status='ok'` with a non-`None` error;\n                non-`ok` status without an error message; non-`ok` status\n                carrying tools; or `pending_reconnect` set without\n                `status='disabled'`.\n        \"\"\"\n        if self.status == \"ok\":\n            if self.error is not None:\n                msg = (\n                    f\"MCPServerInfo {self.name!r}: status='ok' cannot carry \"\n                    f\"an error (got {self.error!r})\"\n                )\n                raise ValueError(msg)\n        else:\n            if self.error is None:\n                msg = (\n                    f\"MCPServerInfo {self.name!r}: status={self.status!r} \"\n                    \"requires an error message\"\n                )\n                raise ValueError(msg)\n            if self.tools:\n                msg = (\n                    f\"MCPServerInfo {self.name!r}: status={self.status!r} \"\n                    \"cannot carry tools\"\n                )\n                raise ValueError(msg)\n        if self.pending_reconnect and self.status != \"disabled\":\n            msg = (\n                f\"MCPServerInfo {self.name!r}: pending_reconnect requires \"\n                f\"status='disabled' (got {self.status!r})\"\n            )\n            raise ValueError(msg)\n\n    def needs_attention(self) -> bool:\n        \"\"\"Return whether this server is blocked on user login.\"\"\"\n        return self.status == \"unauthenticated\"\n\n","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/mcp_tools.py#L167-L203","documentation":"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'.","triggerScenarios":"Constructing `MCPServerInfo(name=..., status='error', error=None)` or `MCPServerInfo(name=..., status='error', error='...', tools=[...])` when aggregating MCP server connection results.","commonSituations":"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.","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."],"exampleFix":"// before\nexcept Exception:\n    infos.append(MCPServerInfo(name=\"notion\", status=\"error\", error=None, tools=[]))\n// after\nexcept Exception as exc:\n    infos.append(MCPServerInfo(name=\"notion\", status=\"error\", error=str(exc), tools=[]))","handlingStrategy":"type-guard","validationCode":"def make_failure_info(name: str, exc: Exception) -> MCPServerInfo:\n    if not str(exc):\n        raise ValueError(\"failure status requires a non-empty error message\")\n    return MCPServerInfo(name=name, status=\"error\", error=str(exc), tools=[])","typeGuard":"def is_valid_failure(info: MCPServerInfo) -> bool:\n    return info.status != \"ok\" and info.error is not None and not info.tools","tryCatchPattern":"try:\n    info = MCPServerInfo(name=name, status=\"error\", error=None)\nexcept ValueError as exc:\n    print(f\"fixing failure info: {exc}\")\n    info = MCPServerInfo(name=name, status=\"error\", error=\"unknown failure\", tools=[])","preventionTips":["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"],"tags":["mcp","invariant","value-error","dataclass"],"backgroundTag":"invariant-violation","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}