langchain-ai/deepagents · error · RuntimeError
SDK {name} tool is unavailable.
Error message
SDK {name} tool is unavailable. What it means
During rubric-grader construction, `_fs_func` looks up a filesystem tool (e.g. `read_file`) in the dict of tools produced by `FilesystemMiddleware` and unwraps its underlying sync callable. If the tool is missing from the dict or its `.func` attribute is None, the middleware did not produce the expected StructuredTool, so a RuntimeError is raised. This is an internal invariant check: the grader cannot work without the wrapped filesystem function.
Source
Thrown at libs/code/deepagents_code/agent.py:546
from langchain_core.messages import ToolMessage as LCToolMessage
repository_tool_names = _rubric_grader_repository_tool_names(fs_tools)
read_file_prefix = _rubric_grader_read_file_prefix(backend)
artifact_filesystem = FilesystemMiddleware(
backend=backend,
tools=["read_file"],
tool_token_limit_before_evict=None,
)
artifact_tools = {
candidate.name: candidate for candidate in artifact_filesystem.tools
}
def _fs_func(tools_by_name: dict[str, BaseTool], name: str) -> Callable[..., Any]:
candidate = cast("StructuredTool | None", tools_by_name.get(name))
if candidate is None or candidate.func is None:
msg = f"SDK {name} tool is unavailable."
raise RuntimeError(msg)
return candidate.func
artifact_read_file = cast("StructuredTool", artifact_tools["read_file"])
artifact_read_file_func = _fs_func(artifact_tools, "read_file")
bounds: RepositoryBounds | None = None
repository_tools: dict[str, BaseTool] = {}
if (
repository_backend is not None
and repository_root is not None
and repository_tool_names
):
try:
bounds = RepositoryBounds(repository_backend, root=repository_root)
except ValueError:
logger.warning(
"Invalid rubric grader repository root %r; disabling "
"working-directory inspection",View on GitHub (pinned to a1af029e6e)
Solutions
- Verify the `deepagents` SDK version matches the exact pin in libs/code/pyproject.toml (e.g. `pip show deepagents`); upgrade/downgrade to the pinned version.
- Confirm the middleware is constructed with the tool name included in its `tools` list (`tools=["read_file"]`) and that the backend supports it.
- If you patch or stub FilesystemMiddleware in tests, ensure the stub returns StructuredTool objects with a non-None `.func`.
Example fix
// before: stubbed middleware returns plain objects artifact_filesystem = FilesystemMiddleware(backend=backend, tools=[]) // after: request the required tool and use a compatible SDK artifact_filesystem = FilesystemMiddleware(backend=backend, tools=["read_file"], tool_token_limit_before_evict=None)
Defensive patterns
Strategy: validation
Validate before calling
from deepagents_code.agent import _create_rubric_grader_tools # or inspect tools yourself
import importlib.metadata
assert importlib.metadata.version("deepagents") == EXPECTED_SDK_PIN, "SDK drift: FilesystemMiddleware may not expose .func"
tool_names = {t.name for t in fs_middleware.tools}
assert "read_file" in tool_names, "read_file missing from FilesystemMiddleware tools" Type guard
def has_sync_func(tool: object) -> bool:
return isinstance(tool, StructuredTool) and getattr(tool, "func", None) is not None Try / catch
try:
grader_tools = _create_rubric_grader_tools(...)
except RuntimeError as e:
if "tool is unavailable" in str(e):
logger.error("SDK filesystem tool missing; check deepagents pin: %s", e)
raise Prevention
- Keep the exact deepagents==X.Y.Z pin from pyproject.toml and bump it deliberately.
- When stubbing FilesystemMiddleware in tests, return real StructuredTool objects with .func set.
- Assert middleware tool names in tests before grading setup runs.
When it happens
Trigger: Calling `_create_rubric_grader_tools` (indirectly via rubric grading setup in `create_cli_agent`) when `FilesystemMiddleware(backend=..., tools=["read_file"], ...)` fails to yield a tool named `read_file`, or yields a StructuredTool whose `.func` is None (e.g. a tool constructed from a coroutine only, or an SDK/deepagents version where FilesystemMiddleware tool construction changed and no sync callable is attached).
Common situations: A pinned `deepagents` SDK version where `FilesystemMiddleware.tools` no longer returns `StructuredTool` objects with a `.func` attribute for the requested tool names; mistyping the requested tool name in the middleware's `tools` list; monkeypatched or stubbed middleware in tests returning empty tool lists.
Related errors
- At least one subagent must be specified
- HarnessProfile.excluded_middleware is invalid: - required
- HarnessProfileConfig.from_harness_profile() cannot export `e
- modes can only be provided when agent is a factory
- models can only be provided when agent is a factory
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/5288638400259d56.
Report an issue: GitHub.