{"record":{"id":"fe990bfa0c4a89df","repo":"langchain-ai/deepagents","slug":"shell-allow-all-should-not-be-used-with-shellallow","errorCode":null,"errorMessage":"SHELL_ALLOW_ALL should not be used with ShellAllowListMiddleware; use auto_approve=True instead","messagePattern":"SHELL_ALLOW_ALL should not be used with ShellAllowListMiddleware; use auto_approve=True instead","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/agent.py","lineNumber":854,"sourceCode":"            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        \"\"\"\n        from langchain_core.messages import ToolMessage as LCToolMessage\n\n        from deepagents_code.config import is_shell_command_allowed\n\n        if request.tool_call[\"name\"] != \"execute\":\n            return None","sourceCodeStart":836,"sourceCodeEnd":872,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/agent.py#L836-L872","documentation":"`SHELL_ALLOW_ALL` is a sentinel meaning 'permit every shell command'. `ShellAllowListMiddleware` is by design a restrictive allow-list; passing the sentinel would silently turn it into allow-everything, defeating its purpose. The constructor detects the sentinel type and raises TypeError, directing you to `auto_approve=True` for unrestricted non-interactive runs.","triggerScenarios":"Instantiating `ShellAllowListMiddleware(SHELL_ALLOW_ALL)` or passing a value whose type matches the sentinel (checked via `isinstance(allow_list, type(SHELL_ALLOW_ALL))`), typically by reading `SHELL_ALLOW_ALL` from config or sharing one allow-list variable between HITL and non-interactive code paths.","commonSituations":"Config that stores `SHELL_ALLOW_ALL` for interactive mode and reuses it when building a headless/non-interactive agent; refactors that replaced HITL approval with the allow-list middleware without swapping the sentinel for `auto_approve=True`.","solutions":["Use `auto_approve=True` in `create_cli_agent` instead of ShellAllowListMiddleware when you want unrestricted, interrupt-free shell execution.","Replace SHELL_ALLOW_ALL with an explicit restrictive list such as [\"ls\", \"cat\", \"grep\"].","Guard shared config: resolve the sentinel to `auto_approve=True` before choosing the middleware."],"exampleFix":"// before\nfrom deepagents_code.config import SHELL_ALLOW_ALL\nmw = ShellAllowListMiddleware(SHELL_ALLOW_ALL)\n// after\nif allow == SHELL_ALLOW_ALL:\n    agent = create_cli_agent(..., auto_approve=True)  # no allow-list middleware\nelse:\n    mw = ShellAllowListMiddleware(allow_list=allow)","handlingStrategy":"type-guard","validationCode":"from deepagents_code.config import SHELL_ALLOW_ALL\nif allow is SHELL_ALLOW_ALL or isinstance(allow, type(SHELL_ALLOW_ALL)):\n    raise TypeError(\"Use auto_approve=True instead of SHELL_ALLOW_ALL with ShellAllowListMiddleware\")","typeGuard":"def is_restrictive_allow_list(value: object) -> bool:\n    from deepagents_code.config import SHELL_ALLOW_ALL\n    return isinstance(value, list) and not isinstance(value, type(SHELL_ALLOW_ALL)) and len(value) > 0","tryCatchPattern":"try:\n    mw = ShellAllowListMiddleware(allow_list=allow)\nexcept TypeError as e:\n    if \"SHELL_ALLOW_ALL\" in str(e):\n        mw = None  # switch to create_cli_agent(..., auto_approve=True)\n    else:\n        raise","preventionTips":["Never feed config values straight into ShellAllowListMiddleware; check for the SHELL_ALLOW_ALL sentinel first.","Map sentinel -> auto_approve=True in one central place, not at each construction site.","Keep restrictive allow-lists explicit literals in config rather than shared constants."],"tags":["python","configuration","type-error","shell","security"],"backgroundTag":"sentinel-misuse","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}