{"record":{"id":"c3b541beb3ed2d5a","repo":"langchain-ai/deepagents","slug":"allow-list-must-not-be-empty-disable-shell-access","errorCode":null,"errorMessage":"allow_list must not be empty; disable shell access instead","messagePattern":"allow_list must not be empty; disable shell access instead","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/agent.py","lineNumber":848,"sourceCode":"    \"\"\"Omit hook inputs from traces by default; set a `TracePolicy` to override.\"\"\"\n\n    def __init__(self, allow_list: list[str]) -> None:\n        \"\"\"Initialize with the shell allow-list to validate commands against.\n\n        Args:\n            allow_list: Allowed command names (e.g. `[\"ls\", \"cat\", \"grep\"]`).\n                Must be a non-empty restrictive list — not `SHELL_ALLOW_ALL`.\n\n        Raises:\n            ValueError: If `allow_list` is empty.\n            TypeError: If `allow_list` is the `SHELL_ALLOW_ALL` sentinel.\n        \"\"\"\n        from deepagents_code.config import SHELL_ALLOW_ALL\n\n        super().__init__()\n        if not allow_list:\n            msg = \"allow_list must not be empty; disable shell access instead\"\n            raise ValueError(msg)\n        if isinstance(allow_list, type(SHELL_ALLOW_ALL)):\n            msg = (\n                \"SHELL_ALLOW_ALL should not be used with \"\n                \"ShellAllowListMiddleware; use auto_approve=True instead\"\n            )\n            raise TypeError(msg)\n        self._allow_list = list(allow_list)\n\n    def _validate_tool_call(self, request: ToolCallRequest) -> ToolMessage | None:\n        \"\"\"Return an error tool message when a shell command is not allowed.\n\n        Args:\n            request: The tool call request being processed.\n\n        Returns:\n            An error `ToolMessage` when the shell command should be rejected,\n            otherwise `None`.\n        \"\"\"","sourceCodeStart":830,"sourceCodeEnd":866,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/agent.py#L830-L866","documentation":"`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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nmiddleware = ShellAllowListMiddleware(allow_list=cfg.get(\"shell_allow\", []))\n// after\nallowed = cfg.get(\"shell_allow\", [])\nif not allowed:\n    middleware = None  # shell access disabled\nelse:\n    middleware = ShellAllowListMiddleware(allow_list=allowed)","handlingStrategy":"validation","validationCode":"allow_list = load_shell_allow_list()  # however you build it\nif allow_list:\n    middleware = ShellAllowListMiddleware(allow_list=allow_list)\nelse:\n    middleware = None  # shell access disabled","typeGuard":"def is_valid_allow_list(value: object) -> bool:\n    return isinstance(value, list) and len(value) > 0 and all(isinstance(c, str) for c in value)","tryCatchPattern":"try:\n    mw = ShellAllowListMiddleware(allow_list=allow_list)\nexcept ValueError as e:\n    if \"allow_list must not be empty\" in str(e):\n        logger.warning(\"Empty shell allow-list; disabling shell access\")\n        mw = None\n    else:\n        raise","preventionTips":["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."],"tags":["python","configuration","validation","shell"],"backgroundTag":"empty-allow-list","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}