rohitg00/ai-engineering-from-scratch · error · ContractViolation
tools/list failed
Error message
tools/list failed
What it means
Error "tools/list failed" thrown in rohitg00/ai-engineering-from-scratch.
Source
Thrown at phases/13-tools-and-protocols/28-mcp-tool-contracts-and-content/code/main.py:699
self.server = server
self.principal = principal
self.max_list_pages = max_list_pages
self.rejections: list[dict[str, str]] = []
self.cursor_trace: list[str | None] = []
self.tools: dict[str, dict[str, Any]] = {}
def discover_tools(self) -> dict[str, dict[str, Any]]:
cursor: str | None = None
request_id = 1
seen_cursors: set[str] = set()
for _ in range(self.max_list_pages):
params: dict[str, Any] = {}
if cursor is not None:
params["cursor"] = cursor
self.cursor_trace.append(cursor)
response = self.server.dispatch(make_request(request_id, "tools/list", params))
if response is None or "error" in response:
raise ContractViolation("tools/list failed")
result = response["result"]
for tool in result["tools"]:
try:
validate_tool_descriptor(tool)
except ContractViolation as exc:
self.rejections.append({"tool": tool.get("name", "<unknown>"), "reason": str(exc)})
continue
self.tools[tool["name"]] = tool
next_cursor = result.get("nextCursor")
if next_cursor is None:
return self.tools
if not isinstance(next_cursor, str):
raise ContractViolation("tools/list nextCursor must be a string or null")
if next_cursor in seen_cursors:
raise ContractViolation("tools/list returned a repeated or cyclic nextCursor")
seen_cursors.add(next_cursor)
cursor = next_cursor
request_id += 1View on GitHub (pinned to 39ea8a1c6d)
When it happens
Trigger: Thrown at phases/13-tools-and-protocols/28-mcp-tool-contracts-and-content/code/main.py:699 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/7ec550c4898b811a.
Report an issue: GitHub.