langchain-ai/deepagents · error · ValueError
allow_list must not be empty; disable shell access instead
Error message
allow_list must not be empty; disable shell access instead
What it means
`ShellAllowListMiddleware` validates shell commands against an explicit allow-list without HITL interrupts. An empty `allow_list` is a configuration contradiction: the middleware would reject every command, so the library raises ValueError at construction and tells you to disable shell access instead of running a no-op/deny-all middleware.
Source
Thrown at libs/code/deepagents_code/agent.py:848
"""Omit hook inputs from traces by default; set a `TracePolicy` to override."""
def __init__(self, allow_list: list[str]) -> None:
"""Initialize with the shell allow-list to validate commands against.
Args:
allow_list: Allowed command names (e.g. `["ls", "cat", "grep"]`).
Must be a non-empty restrictive list — not `SHELL_ALLOW_ALL`.
Raises:
ValueError: If `allow_list` is empty.
TypeError: If `allow_list` is the `SHELL_ALLOW_ALL` sentinel.
"""
from deepagents_code.config import SHELL_ALLOW_ALL
super().__init__()
if not allow_list:
msg = "allow_list must not be empty; disable shell access instead"
raise ValueError(msg)
if isinstance(allow_list, type(SHELL_ALLOW_ALL)):
msg = (
"SHELL_ALLOW_ALL should not be used with "
"ShellAllowListMiddleware; use auto_approve=True instead"
)
raise TypeError(msg)
self._allow_list = list(allow_list)
def _validate_tool_call(self, request: ToolCallRequest) -> ToolMessage | None:
"""Return an error tool message when a shell command is not allowed.
Args:
request: The tool call request being processed.
Returns:
An error `ToolMessage` when the shell command should be rejected,
otherwise `None`.
"""View on GitHub (pinned to a1af029e6e)
Solutions
- Pass a non-empty list of allowed command names, e.g. ShellAllowListMiddleware(["ls", "cat", "grep"]).
- If no shell commands should run, don't construct the middleware at all — omit it (or exclude the execute tool) so shell access is disabled.
- Check where the list is built (config/env parsing) and handle the empty case before constructing the middleware.
Example fix
// before
middleware = ShellAllowListMiddleware(allow_list=cfg.get("shell_allow", []))
// after
allowed = cfg.get("shell_allow", [])
if not allowed:
middleware = None # shell access disabled
else:
middleware = ShellAllowListMiddleware(allow_list=allowed) Defensive patterns
Strategy: validation
Validate before calling
allow_list = load_shell_allow_list() # however you build it
if allow_list:
middleware = ShellAllowListMiddleware(allow_list=allow_list)
else:
middleware = None # shell access disabled Type guard
def is_valid_allow_list(value: object) -> bool:
return isinstance(value, list) and len(value) > 0 and all(isinstance(c, str) for c in value) Try / catch
try:
mw = ShellAllowListMiddleware(allow_list=allow_list)
except ValueError as e:
if "allow_list must not be empty" in str(e):
logger.warning("Empty shell allow-list; disabling shell access")
mw = None
else:
raise Prevention
- Validate config-driven allow-lists are non-empty before agent construction.
- Treat an empty list as 'shell disabled', never as a middleware argument.
- Log when an allow-list is filtered down so an empty result is visible.
When it happens
Trigger: Instantiating `ShellAllowListMiddleware(allow_list=[])` or `ShellAllowListMiddleware(allow_list=some_list)` where `some_list` is an empty list/tuple built at runtime (e.g. from an empty config value or env-parsed list).
Common situations: A config file section like `[shell] allow = []`; an env var parsed into an empty list; code that filters an allow-list down to nothing before constructing the middleware.
Related errors
- SHELL_ALLOW_ALL should not be used with ShellAllowListMiddle
- interpreter_ptc='all' exposes every host tool to PTC calls t
- Invalid interpreter_ptc string {ptc!r}; expected 'safe', 'al
- interpreter_ptc list entries cannot include 'all'; use 'all'
- interpreter_ptc must be False, 'safe', 'all', or a list of t
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/c3b541beb3ed2d5a.
Report an issue: GitHub.