langchain-ai/deepagents · error · FleetImportError
{source}: {_display_path(path)}: malformed tools.json: expec
Error message
{source}: {_display_path(path)}: malformed tools.json: expected tools list What it means
FleetImportError raised by _load_tool_requests while parsing a tools.json for fleet MCP import. The file was valid JSON and a valid object, but its top-level 'tools' key is missing or not a list. The library requires an explicit JSON array of tool request objects.
Source
Thrown at libs/talon/deepagents_talon/fleet_import.py:366
def _load_tool_requests(path: Path, scope: str, source: Path) -> list[_ToolRequest]:
try:
data = json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError as exc:
msg = f"{source}: {_display_path(path)}: malformed tools.json: {exc.msg}"
raise FleetImportError(msg) from exc
except OSError as exc:
msg = f"{source}: {_display_path(path)}: {exc}"
raise FleetImportError(msg) from exc
if not isinstance(data, dict):
msg = f"{source}: {_display_path(path)}: malformed tools.json: expected object"
raise FleetImportError(msg)
raw_tools = data.get("tools")
if not isinstance(raw_tools, list):
msg = f"{source}: {_display_path(path)}: malformed tools.json: expected tools list"
raise FleetImportError(msg)
interrupt_config = data.get("interrupt_config")
interrupts = interrupt_config if isinstance(interrupt_config, dict) else {}
requests: list[_ToolRequest] = []
for index, item in enumerate(raw_tools):
if not isinstance(item, dict):
msg = f"{source}: {_display_path(path)}: tools[{index}] must be an object"
raise FleetImportError(msg)
tool = cast("Mapping[str, object]", item)
name = _required_str(tool, "name", path, index, source)
server_url = _sanitize_server_url(
_required_str(tool, "mcp_server_url", path, index, source)
)
server_name = _required_str(tool, "mcp_server_name", path, index, source)
requests.append(
_ToolRequest(
name=name,
server_url=server_url,View on GitHub (pinned to a1af029e6e)
Solutions
- Open the tools.json at the displayed path and add a top-level 'tools' key containing a JSON array
- If the file is a different schema version, regenerate it with the matching fleet export tooling
- Validate the JSON structure with a schema check before importing
Example fix
// before
{"mcpUrl": "https://example.com"}
// after
{"tools": [{"name": "my-tool", "mcp_server_url": "https://example.com", "mcp_server_name": "example"}]} Defensive patterns
Strategy: validation
Validate before calling
import json
data = json.loads(path.read_text())
if not isinstance(data.get("tools"), list):
raise ValueError(f"{path}: 'tools' must be a list") Type guard
def has_tools_list(data: object) -> TypeGuard[dict[str, list[object]]]:
return isinstance(data, dict) and isinstance(data.get("tools"), list) Try / catch
try:
summaries = _mcp_summaries(...)
except FleetImportError as exc:
logger.error("Invalid fleet tools.json: %s", exc)
return [] Prevention
- Validate tools.json against the expected schema in CI
- Regenerate the file with official export tooling rather than hand-editing
- Add a startup schema check before import
When it happens
Trigger: Calling _mcp_summaries/_load_tool_requests on a tools.json whose 'tools' key is absent, set to null, or is a dict/string instead of a JSON array.
Common situations: Hand-edited or partial fleet export files; a tools.json written as a bare object '{"tool": ...}' instead of '{"tools": [...]}'; schema drift between talon versions; truncated/merged config files.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid MCP config at {mcp_config_path}: {exc}
- {source}: {_display_path(path)}: tools[{index}] must be an o
- {source}: {_display_path(path)}: tools[{index}].{key} must b
- Server '{server_name}' cannot set both 'allowedTools' and 'd
- Server '{server_name}' '{field_name}' must be a list of stri
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/17f60178629aa6cc.
Report an issue: GitHub.