{"record":{"id":"1b447749e9f50f29","repo":"infiniflow/ragflow","slug":"execution-timed-out-after-timeout-seconds-1b4477","errorCode":null,"errorMessage":"Execution timed out after {timeout} seconds","messagePattern":"Execution timed out after (.+?) seconds","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"agent/sandbox/providers/ssh.py","lineNumber":591,"sourceCode":"        stdin, stdout_stream, stderr_stream = client.exec_command(command, timeout=timeout)\n        stdin.close()\n        channel = stdout_stream.channel\n\n        stdout_chunks: list[bytes] = []\n        stderr_chunks: list[bytes] = []\n        deadline = time.time() + timeout\n\n        while True:\n            while channel.recv_ready():\n                stdout_chunks.append(channel.recv(65536))\n            while channel.recv_stderr_ready():\n                stderr_chunks.append(channel.recv_stderr(65536))\n\n            if channel.exit_status_ready():\n                break\n            if time.time() > deadline:\n                channel.close()\n                raise TimeoutError(f\"Execution timed out after {timeout} seconds\")\n            time.sleep(0.1)\n\n        while channel.recv_ready():\n            stdout_chunks.append(channel.recv(65536))\n        while channel.recv_stderr_ready():\n            stderr_chunks.append(channel.recv_stderr(65536))\n\n        exit_code = channel.recv_exit_status()\n        stdout = b\"\".join(stdout_chunks).decode(\"utf-8\", errors=\"replace\")\n        stderr = b\"\".join(stderr_chunks).decode(\"utf-8\", errors=\"replace\")\n        return stdout, stderr, exit_code\n\n    def _validate_output_size(self, stdout: str, stderr: str) -> None:\n        output_size = len((stdout or \"\").encode(\"utf-8\")) + len((stderr or \"\").encode(\"utf-8\"))\n        if output_size > self.max_output_bytes:\n            raise RuntimeError(f\"SSH execution output exceeded {self.max_output_bytes} bytes.\")\n\n    def _collect_artifacts(","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/sandbox/providers/ssh.py#L573-L609","documentation":"Raised as TimeoutError by _run_remote_command when the remote channel has not reached exit-status-ready before the deadline (time.time() > deadline). The loop polls recv_ready/recv_stderr_ready every 0.1s; on expiry it closes the channel and raises. This wraps every remote command including code execution (exec_timeout = min(requested_timeout, self.timeout)) and the connectivity probe.","triggerScenarios":"User code that runs longer than the effective timeout (e.g. sleep 60 with timeout=30); deadlocked or infinite-loop scripts; a congested network where the channel stalls; the provider-level self.timeout (default 30s) silently clamping a larger requested timeout — a request for 120s with provider timeout 30 still times out at 30s.","commonSituations":"Forgetting that initialize(config['timeout']=30) caps per-call timeouts, so long jobs die early; running model training / large downloads inside the sandbox; remote under heavy load making even 'true' slow.","solutions":["Raise the provider-level timeout at initialize: config {'timeout': 300} — it is the hard cap for every command","Pass an explicit per-call timeout <= provider timeout: execute_code(..., timeout=300)","Move long-running work out of the sandbox or chunk it with checkpoints","Catch TimeoutError and treat the result as failed (the channel is closed; output so far is lost)"],"exampleFix":"# before\nprovider.initialize({..., \"timeout\": 30})\nprovider.execute_code(inst, \"import time; time.sleep(60)\", \"python\", timeout=120)  # dies at 30s\n\n# after\nprovider.initialize({..., \"timeout\": 300})\nprovider.execute_code(inst, \"import time; time.sleep(60)\", \"python\", timeout=120)","handlingStrategy":"try-catch","validationCode":"effective_timeout = min(int(call_timeout or provider.timeout), provider.timeout)\nif effective_timeout < expected_runtime_seconds:\n    raise RuntimeError(f\"provider timeout {effective_timeout}s below expected runtime; raise config timeout\")","typeGuard":null,"tryCatchPattern":"try:\n    result = provider.execute_code(instance_id, code, language, timeout=90)\nexcept TimeoutError:\n    result = ExecutionResult(stdout=\"\", stderr=\"execution timed out\", exit_code=-1)","preventionTips":["Set the provider-level timeout above your longest expected job — it caps every per-call timeout","Chunk long tasks into resumable steps inside the sandbox","Treat TimeoutError as non-retryable-with-same-inputs: the channel is closed and partial output is lost"],"tags":["timeout","ssh","execution","long-running"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}