{"record":{"id":"ed6b3ab2c85b1e84","repo":"langchain-ai/deepagents","slug":"source-display-path-path-tools-index-k","errorCode":null,"errorMessage":"{source}: {_display_path(path)}: tools[{index}].{key} must be a non-empty string","messagePattern":"(.+?): (.+?): tools\\[(.+?)\\]\\.(.+?) must be a non-empty string","errorType":"error_code","errorClass":"FleetImportError","httpStatus":null,"severity":"error","filePath":"libs/talon/deepagents_talon/fleet_import.py","lineNumber":403,"sourceCode":"                server_name=server_name,\n                scope=scope,\n                interrupt=_tool_interrupt_enabled(tool, interrupts, name, server_url, server_name),\n            )\n        )\n    return requests\n\n\ndef _required_str(\n    item: Mapping[str, object],\n    key: str,\n    path: Path,\n    index: int,\n    source: Path,\n) -> str:\n    value = item.get(key)\n    if not isinstance(value, str) or not value:\n        msg = f\"{source}: {_display_path(path)}: tools[{index}].{key} must be a non-empty string\"\n        raise FleetImportError(msg)\n    return value\n\n\ndef _tool_interrupt_enabled(\n    item: Mapping[str, object],\n    interrupts: Mapping[object, object],\n    name: str,\n    server_url: str,\n    server_name: str,\n) -> bool:\n    if item.get(\"interrupt_config\") is True:\n        return True\n    keys = (\n        f\"{server_url}::{name}::{server_name}\",\n        f\"{_unsanitized_url(item)}::{name}::{server_name}\",\n        name,\n    )\n    return any(interrupts.get(key) is True for key in keys)","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/talon/deepagents_talon/fleet_import.py#L385-L421","documentation":"FleetImportError raised by _required_str when a required string field on a tools.json entry is missing, not a string, or an empty string. Used for fields like name, mcp_server_url, and mcp_server_name.","triggerScenarios":"A tool object in tools.json omits a required key, sets it to null/number/bool, or sets it to \"\"; the error names the exact index and key.","commonSituations":"Placeholder values left as empty strings after template fill; renaming a key (e.g. 'server' vs 'mcp_server_name'); YAML-to-JSON conversion turning empty values into null or omitting them.","solutions":["Set the named key at tools[index] to a non-empty string (e.g. a valid MCP server URL)","Check for key renames/spelling differences between your file and the expected schema","Re-generate the tools.json from the fleet source to get correct defaults"],"exampleFix":"// before\n{\"name\": \"\", \"mcp_server_url\": \"https://example.com\", \"mcp_server_name\": \"example\"}\n// after\n{\"name\": \"my-tool\", \"mcp_server_url\": \"https://example.com\", \"mcp_server_name\": \"example\"}","handlingStrategy":"validation","validationCode":"REQUIRED = (\"name\", \"mcp_server_url\", \"mcp_server_name\")\nfor i, tool in enumerate(data[\"tools\"]):\n    missing = [k for k in REQUIRED if not isinstance(tool.get(k), str) or not tool.get(k)]\n    if missing:\n        raise ValueError(f\"tools[{i}] missing/empty: {missing}\")","typeGuard":"def is_nonempty_str(v: object) -> TypeGuard[str]:\n    return isinstance(v, str) and bool(v)","tryCatchPattern":"try:\n    summaries = _mcp_summaries(...)\nexcept FleetImportError as exc:\n    logger.error(\"tools.json field invalid: %s\", exc)\n    raise","preventionTips":["Fill all template placeholders; grep for empty string values before import","Keep a schema/example tools.json checked into the repo","Check key names against the expected schema after any rename"],"tags":["json","config","validation","mcp"],"backgroundTag":"schema-validation-failed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}