{"record":{"id":"f48924a32133e2f3","repo":"infiniflow/ragflow","slug":"sandbox-local-timeout-must-be-greater-than-0","errorCode":null,"errorMessage":"SANDBOX_LOCAL_TIMEOUT must be greater than 0.","messagePattern":"SANDBOX_LOCAL_TIMEOUT must be greater than 0\\.","errorType":"exception","errorClass":"SandboxProviderConfigError","httpStatus":null,"severity":"error","filePath":"agent/sandbox/providers/local.py","lineNumber":260,"sourceCode":"                \"label\": \"Max Artifacts\",\n                \"description\": \"Maximum number of files collected from the artifacts directory.\",\n                \"min\": 0,\n                \"max\": 100,\n            },\n            \"max_artifact_bytes\": {\n                \"type\": \"integer\",\n                \"required\": False,\n                \"default\": 10485760,\n                \"label\": \"Max Artifact Size (bytes)\",\n                \"description\": \"Maximum size of a single artifact file. Unit: bytes.\",\n                \"min\": 1024,\n                \"max\": 104857600,\n            },\n        }\n\n    def _validate_limits(self) -> None:\n        if self.timeout <= 0:\n            raise SandboxProviderConfigError(\"SANDBOX_LOCAL_TIMEOUT must be greater than 0.\")\n        if self.max_memory_mb <= 0:\n            raise SandboxProviderConfigError(\"SANDBOX_LOCAL_MAX_MEMORY_MB must be greater than 0.\")\n        if self.max_output_bytes <= 0:\n            raise SandboxProviderConfigError(\"SANDBOX_LOCAL_MAX_OUTPUT_BYTES must be greater than 0.\")\n        if self.max_artifacts < 0:\n            raise SandboxProviderConfigError(\"SANDBOX_LOCAL_MAX_ARTIFACTS must be greater than or equal to 0.\")\n        if self.max_artifact_bytes <= 0:\n            raise SandboxProviderConfigError(\"SANDBOX_LOCAL_MAX_ARTIFACT_BYTES must be greater than 0.\")\n\n    def _prepare_script(self, instance_dir: Path, language: str, code: str, args_json: str) -> tuple[list[str], Path]:\n        if language == \"python\":\n            script_path = instance_dir / \"main.py\"\n            script_path.write_text(build_python_wrapper(code, args_json), encoding=\"utf-8\")\n            return [self.python_bin, str(script_path)], script_path\n        if language in {\"javascript\", \"nodejs\"}:\n            script_path = instance_dir / \"main.js\"\n            script_path.write_text(build_javascript_wrapper(code, args_json), encoding=\"utf-8\")\n            return [self.node_bin, str(script_path)], script_path","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/sandbox/providers/local.py#L242-L278","documentation":"Raised by LocalProvider._validate_limits() during initialize() when the configured 'timeout' value is zero or negative. LocalProvider runs agent code as a child process on the host, and a non-positive timeout would make subprocess timeout enforcement meaningless, so initialization fails fast with SandboxProviderConfigError. The value comes from config['timeout'] (default 30) passed to initialize().","triggerScenarios":"Calling LocalProvider().initialize({'timeout': 0}) or initialize({'timeout': -5}); also passing a string like '0' which int() coerces to 0. Any config source (env var mapping, YAML, DB-stored provider config) that yields timeout <= 0 triggers this before any instance is created.","commonSituations":"Misreading 'timeout' as milliseconds and setting e.g. 500 expecting sub-second (still valid) or 0 meaning 'no limit'; a deployment pipeline templating an empty/zero timeout variable into the sandbox config; disabling timeouts by convention (0 = unlimited) which this provider does not support.","solutions":["Set 'timeout' to a positive integer number of seconds (e.g. 30) in the LocalProvider config dict passed to initialize().","If the value comes from an env var or template, check the rendered config and fix the upstream variable (e.g. SANDBOX_LOCAL_TIMEOUT=30).","Omit the 'timeout' key entirely to accept the default of 30 seconds.","If you need a per-run timeout, keep initialize() valid and pass the timeout argument to execute_code() instead — it is clamped to the provider maximum anyway."],"exampleFix":"// before\nprovider = LocalProvider()\nprovider.initialize({\"timeout\": 0})\n\n// after\nprovider = LocalProvider()\nprovider.initialize({\"timeout\": 30})","handlingStrategy":"validation","validationCode":"def valid_local_config(config: dict) -> bool:\n    return int(config.get(\"timeout\", 30)) > 0","typeGuard":null,"tryCatchPattern":"from agent.sandbox.providers.base import SandboxProviderConfigError\ntry:\n    provider.initialize(config)\nexcept SandboxProviderConfigError as e:\n    if \"SANDBOX_LOCAL_TIMEOUT\" in str(e):\n        config[\"timeout\"] = 30\n        provider.initialize(config)\n    else:\n        raise","preventionTips":["Validate sandbox config dicts against provider.get_config_schema() (types, min/max) before initialize().","Never use 0 or -1 as 'unlimited' sentinels — this provider requires positive limits.","Centralize sandbox config in one place and unit-test it with the provider's own validators."],"tags":["sandbox","configuration","local-provider","validation"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}