langchain-ai/deepagents · error · ValueError
Cannot enforce --allow-fs-tools on compiled subagent {subage
Error message
Cannot enforce --allow-fs-tools on compiled subagent {subagent.get('name', '<unnamed>')!r}: its middleware is not configurable, so the filesystem restriction would be silently bypassed. What it means
When --allow-fs-tools is used, create_cli_agent injects filesystem restrictions into each subagent's middleware. A subagent supplied as an already-compiled graph (the 'runnable' branch of the SubAgent union) has no configurable middleware, so the restriction could not be applied — the code raises instead of silently allowing the subagent to bypass the filesystem restriction.
Source
Thrown at libs/code/deepagents_code/agent.py:262
Raises:
ValueError: If a `CompiledSubAgent` (identified by a `"runnable"` key,
matching the SDK's own `"runnable" in spec` discriminator in
`deepagents.middleware.subagents`) is present. Such a spec is used
as-is by the SDK and its `middleware`
key is never read, so we cannot enforce the restriction on it. dcode
adds only raw `SubAgent` dicts today, but the declared type admits
compiled specs: fail loud rather than silently exposing an
unrestricted filesystem via `task` delegation.
"""
for subagent in custom_subagents:
if "runnable" in subagent:
msg = (
"Cannot enforce --allow-fs-tools on compiled subagent "
f"{subagent.get('name', '<unnamed>')!r}: its middleware is "
"not configurable, so the filesystem restriction would be "
"silently bypassed."
)
raise ValueError(msg)
# `"runnable" in subagent` above narrows the union to `SubAgent`.
subagent_tool_descriptions = (
_get_harness_tool_descriptions(subagent["model"])
if "model" in subagent
else main_tool_descriptions
)
subagent["middleware"] = cast(
"list[AgentMiddleware]",
[
*subagent.get("middleware", []),
FilesystemMiddleware(
backend=backend,
tools=fs_tools,
custom_tool_descriptions=subagent_tool_descriptions,
),
],
)
View on GitHub (pinned to a1af029e6e)
Solutions
- Replace the compiled subagent with a declarative SubAgent dict (name/model/prompt/tools/middleware) so _inject_fs_tools_into_subagents can configure its middleware.
- If the subagent must stay compiled, wrap or rebuild its graph with the equivalent filesystem-restricting middleware yourself before passing it in.
- Disable --allow-fs-tools only if you can guarantee the compiled subagent exposes no unrestricted filesystem tools; otherwise it is not a valid alternative.
Example fix
# before
subagents = [{"name": "researcher", "runnable": compiled_graph}]
create_cli_agent(subagents=subagents, allow_fs_tools=True)
# after
subagents = [{"name": "researcher", "model": "...", "prompt": "..."}]
create_cli_agent(subagents=subagents, allow_fs_tools=True) Defensive patterns
Strategy: validation
Validate before calling
def assert_fs_tools_enforceable(subagents, allow_fs_tools):
if not allow_fs_tools:
return
for s in subagents:
if "runnable" in s:
raise ValueError(
f"Cannot enforce --allow-fs-tools on compiled subagent {s.get('name', '<unnamed>')!r}; "
"use a declarative subagent instead"
) Type guard
def is_declarative_subagent(s: dict) -> bool:
return "runnable" not in s and "name" in s Try / catch
try:
agent = create_cli_agent(subagents=subagents, allow_fs_tools=True)
except ValueError as exc:
if "compiled subagent" in str(exc):
subagents = [declarative_form(s) for s in subagents]
agent = create_cli_agent(subagents=subagents, allow_fs_tools=True)
else:
raise Prevention
- When using --allow-fs-tools, always pass declarative subagent dicts, never compiled graphs.
- If you need pre-compiled graphs, apply the filesystem-restricting middleware inside the graph yourself and document it.
- Audit subagent tool lists for unrestricted filesystem tools before enabling sandboxed runs.
When it happens
Trigger: Calling create_cli_agent with --allow-fs-tools enabled and a subagents list containing a compiled subagent (a dict with a 'runnable' key, e.g. {'name': ..., 'runnable': compiled_graph}). Also reproduced by the test test_compiled_subagent_raises_rather_than_bypassing.
Common situations: Users composing pre-compiled LangGraph subagents for performance/reuse while simultaneously trying to sandbox filesystem tool access; copying agent definitions that embed compiled graphs.
Related errors
- Cannot combine 'all' with other commands in --shell-allow-li
- `interpreter_ptc` list entries cannot include 'all'; use 'al
- modes can only be provided when agent is a factory
- models can only be provided when agent is a factory
- -32601
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/734a985ca5afe15d.
Report an issue: GitHub.