{"record":{"id":"053b48632ca0f102","repo":"langchain-ai/deepagents","slug":"interpreter-ptc-must-be-false-safe-all-or-a","errorCode":null,"errorMessage":"interpreter_ptc must be False, 'safe', 'all', or a list of tool names; got {type(ptc).__name__}.","messagePattern":"interpreter_ptc must be False, 'safe', 'all', or a list of tool names; got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/agent.py","lineNumber":1084,"sourceCode":"            _add(name)\n\n        # Explicit names are passed through unvalidated: the middleware resolves\n        # them against the live runtime registry (which includes the SDK\n        # built-ins absent from `tools`) and drops any that match nothing.\n        absent = sorted(n for n in resolved if n not in live_set)\n        if absent:\n            logger.debug(\n                \"interpreter_ptc names not in the build-time toolset (resolved \"\n                \"at runtime if present): %s\",\n                absent,\n            )\n        return resolved\n\n    msg = (\n        \"interpreter_ptc must be False, 'safe', 'all', or a list of tool names; \"\n        f\"got {type(ptc).__name__}.\"\n    )\n    raise ValueError(msg)\n\n\ndef _resolve_shell_allow_list() -> list[str] | None:\n    \"\"\"Resolve the shell allow-list for a direct agent-construction caller.\n\n    Returns:\n        The configured allow-list, or `None` when shell access is disabled.\n\n    Raises:\n        RuntimeError: If the option is absent from the manifest.\n    \"\"\"\n    from deepagents_code.config_manifest import _emit_ranked_diagnostics, get_option\n    from deepagents_code.configuration.resolver import get_config_resolver\n\n    option = get_option(\"shell.allow_list\")\n    if option is None:\n        msg = \"shell.allow_list is missing from the configuration manifest\"\n        raise RuntimeError(msg)","sourceCodeStart":1066,"sourceCodeEnd":1102,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/agent.py#L1066-L1102","documentation":"interpreter_ptc accepts only False, the strings 'safe'/'all', or a list of tool names. Any other type (int, True, dict, tuple, None, a Tool object) reaches the fallthrough and raises this ValueError naming the offending type. It is the type-level guard at the end of _resolve_ptc_option.","triggerScenarios":"create_cli_agent(interpreter_ptc=True), interpreter_ptc=1, interpreter_ptc=None, interpreter_ptc=(\"execute\",), interpreter_ptc={\"tools\": [...]}, or a non-str/non-list value read from a YAML/JSON config where the type was not coerced.","commonSituations":"YAML parsing interpreter_ptc: yes as True; JSON config with null; passing a tuple instead of a list; wiring a config parser's default (None) straight through instead of False.","solutions":["Disable PTC with the boolean False (not None, not 0-dependent truthiness): interpreter_ptc=False.","Use \"safe\" or \"all\" as strings, or a real list of tool names.","Coerce/validate the value where it is loaded from config before passing it to create_cli_agent."],"exampleFix":"// before\nptc = config.get(\"interpreter_ptc\")  # None when unset\ncreate_cli_agent(interpreter_ptc=ptc)\n// after\nptc = config.get(\"interpreter_ptc\", False)\nif isinstance(ptc, tuple):\n    ptc = list(ptc)\ncreate_cli_agent(interpreter_ptc=ptc)","handlingStrategy":"type-guard","validationCode":"def coerce_ptc(v: object) -> bool | str | list[str]:\n    if v is None:\n        return False\n    if isinstance(v, tuple):\n        return list(v)\n    if v is False or (isinstance(v, str) and v.strip().lower() in {\"safe\", \"all\"}):\n        return v\n    if isinstance(v, list) and all(isinstance(n, str) for n in v):\n        return v\n    raise TypeError(f\"unsupported interpreter_ptc value: {v!r}\")","typeGuard":"from typing import TypeGuard\n\ndef is_valid_ptc(v: object) -> TypeGuard[bool | str | list[str]]:\n    if isinstance(v, bool):\n        return v is False\n    if isinstance(v, str):\n        return v.strip().lower() in {\"safe\", \"all\"}\n    return isinstance(v, list) and all(isinstance(n, str) for n in v)","tryCatchPattern":"try:\n    agent = create_cli_agent(interpreter_ptc=ptc)\nexcept ValueError as exc:\n    logger.error(\"interpreter_ptc type rejected (%s); defaulting to False\", exc)\n    agent = create_cli_agent(interpreter_ptc=False)","preventionTips":["Never pass None or True; disable PTC with the literal False.","Convert config tuples/sets to list[str] before passing.","Annotate the variable as bool | str | list[str] so type checkers catch bad assignments."],"tags":["python","type-error","configuration","validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}