langchain-ai/deepagents · error · FleetImportError
{source}: {_display_path(path)}: tools[{index}] must be an o
Error message
{source}: {_display_path(path)}: tools[{index}] must be an object What it means
FleetImportError raised when an element of the tools list in tools.json is not a JSON object. Each entry of the 'tools' array must be a mapping of tool fields (name, mcp_server_url, mcp_server_name).
Source
Thrown at libs/talon/deepagents_talon/fleet_import.py:374
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,
server_name=server_name,
scope=scope,
interrupt=_tool_interrupt_enabled(tool, interrupts, name, server_url, server_name),
)
)
return requests
View on GitHub (pinned to a1af029e6e)
Solutions
- Fix the array element at the reported index so it is a JSON object with name, mcp_server_url, and mcp_server_name fields
- Re-export the fleet tools.json from source if it was generated
- Lint the file (e.g. jq '.tools | map(type)' tools.json) to find non-object entries
Example fix
// before
{"tools": ["my-tool"]}
// after
{"tools": [{"name": "my-tool", "mcp_server_url": "https://example.com", "mcp_server_name": "example"}]} Defensive patterns
Strategy: validation
Validate before calling
data = json.loads(path.read_text())
bad = [i for i, t in enumerate(data.get("tools", [])) if not isinstance(t, dict)]
if bad:
raise ValueError(f"non-object tool entries at indexes {bad}") Type guard
def is_tool_entry(item: object) -> TypeGuard[dict[str, object]]:
return isinstance(item, dict) Try / catch
try:
summaries = _mcp_summaries(...)
except FleetImportError as exc:
logger.error("Bad tool entry in tools.json: %s", exc)
raise Prevention
- Run jq '.tools | map(type)' to verify all entries are objects
- Never hand-edit generated tools.json entries
- Round-trip parse the file before import
When it happens
Trigger: A tools.json entry like "tools": ["name-only"] or [123] or [null]; iterating raw_tools with enumerate hits a non-dict item at the reported index.
Common situations: Hand-editing the list and dropping braces around an entry; JSON minifiers or scripts emitting scalars; copy-paste losing the object structure of one tool.
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.
Related errors
- Invalid MCP config at {mcp_config_path}: {exc}
- {source}: {_display_path(path)}: malformed tools.json: expec
- {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/1a0d92093069fe6c.
Report an issue: GitHub.