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

  1. 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.
  2. Confirm the middleware is constructed with the tool name included in its `tools` list (`tools=["read_file"]`) and that the backend supports it.
  3. 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

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


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/5288638400259d56. Report an issue: GitHub.