{"record":{"id":"04821ce261fafab7","repo":"langchain-ai/deepagents","slug":"recursion-limit-must-be-none-or-a-positive-integer","errorCode":null,"errorMessage":"recursion_limit must be None or a positive integer","messagePattern":"recursion_limit must be None or a positive integer","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/_server_config.py","lineNumber":512,"sourceCode":"                raise ValueError(msg)\n            if \"read_file\" not in self.allow_fs_tools:\n                msg = \"allow_fs_tools must include 'read_file'\"\n                raise ValueError(msg)\n        if isinstance(self.rubric_max_iterations, bool):\n            msg = \"rubric_max_iterations must be None or a positive integer\"\n            raise TypeError(msg)\n        if self.rubric_max_iterations is not None and self.rubric_max_iterations <= 0:\n            msg = \"rubric_max_iterations must be None or a positive integer\"\n            raise ValueError(msg)\n        if isinstance(self.cli_max_retries, bool):\n            msg = \"cli_max_retries must be None or a non-negative integer\"\n            raise TypeError(msg)\n        if self.cli_max_retries is not None and self.cli_max_retries < 0:\n            msg = \"cli_max_retries must be None or a non-negative integer\"\n            raise ValueError(msg)\n        if isinstance(self.recursion_limit, bool):\n            msg = \"recursion_limit must be None or a positive integer\"\n            raise TypeError(msg)\n        if self.recursion_limit is not None and self.recursion_limit <= 0:\n            msg = \"recursion_limit must be None or a positive integer\"\n            raise ValueError(msg)\n\n    # ------------------------------------------------------------------\n    # Serialization\n    # ------------------------------------------------------------------\n\n    def to_env(self) -> dict[str, str | None]:\n        \"\"\"Serialize this config to a `DEEPAGENTS_CODE_SERVER_*` env-var mapping.\n\n        `None` values signal that the variable should be *cleared* from the\n        environment (rather than set to an empty string), so callers can\n        iterate and set or clear each variable in `os.environ`.\n\n        Returns:\n            Dict mapping env-var suffixes (without the prefix) to their\n                string values or `None`.","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/_server_config.py#L494-L530","documentation":"ServerConfig.__post_init__ validates that recursion_limit is either None (unlimited/default) or a positive integer. A bool raises TypeError because bool is a subclass of int in Python and passing True/False is almost always a config bug, not an intentional limit. This prevents silently treating True as 1.","triggerScenarios":"Constructing ServerConfig (directly or via from_cli_args/deserialization) with recursion_limit=True or False, or recursion_limit=0 or a negative integer, triggers __post_init__ at line 512 (TypeError) or 514 (ValueError).","commonSituations":"YAML/JSON config files where a boolean flag was placed in the recursion_limit key; CLI/env parsing code that passes a truthy/falsy value instead of an int; template configs left as recursion_limit: true.","solutions":["Set recursion_limit to a positive integer such as 25, or omit it / explicitly set it to null for the default.","If the value comes from a config file or env var, coerce it with int(value) and skip the key when unset or empty.","Search your config loading code for bool coercion (e.g. strtobool) that may convert 'true' into a bool before reaching ServerConfig."],"exampleFix":"# before\nServerConfig(recursion_limit=True)\n# after\nServerConfig(recursion_limit=25)  # or None","handlingStrategy":"validation","validationCode":"def valid_recursion_limit(v):\n    return v is None or (isinstance(v, int) and not isinstance(v, bool) and v > 0)\nif not valid_recursion_limit(cfg.get(\"recursion_limit\")):\n    raise ValueError(\"recursion_limit must be None or a positive integer\")","typeGuard":"def is_recursion_limit(v) -> bool:\n    return v is None or (isinstance(v, int) and not isinstance(v, bool) and v > 0)","tryCatchPattern":null,"preventionTips":["Never put boolean flags in numeric limit fields in config files.","Coerce/validate config values at load time with a schema (pydantic) before constructing ServerConfig.","Use None (null) explicitly for 'use default' instead of 0/-1/True."],"tags":["config","validation","python"],"backgroundTag":"invalid-config-value","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}