infiniflow/ragflow · error · TimeoutError

Execution timed out after {timeout} seconds

Error message

Execution timed out after {timeout} seconds

What it means

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.

Source

Thrown at agent/sandbox/providers/ssh.py:591

        stdin, stdout_stream, stderr_stream = client.exec_command(command, timeout=timeout)
        stdin.close()
        channel = stdout_stream.channel

        stdout_chunks: list[bytes] = []
        stderr_chunks: list[bytes] = []
        deadline = time.time() + timeout

        while True:
            while channel.recv_ready():
                stdout_chunks.append(channel.recv(65536))
            while channel.recv_stderr_ready():
                stderr_chunks.append(channel.recv_stderr(65536))

            if channel.exit_status_ready():
                break
            if time.time() > deadline:
                channel.close()
                raise TimeoutError(f"Execution timed out after {timeout} seconds")
            time.sleep(0.1)

        while channel.recv_ready():
            stdout_chunks.append(channel.recv(65536))
        while channel.recv_stderr_ready():
            stderr_chunks.append(channel.recv_stderr(65536))

        exit_code = channel.recv_exit_status()
        stdout = b"".join(stdout_chunks).decode("utf-8", errors="replace")
        stderr = b"".join(stderr_chunks).decode("utf-8", errors="replace")
        return stdout, stderr, exit_code

    def _validate_output_size(self, stdout: str, stderr: str) -> None:
        output_size = len((stdout or "").encode("utf-8")) + len((stderr or "").encode("utf-8"))
        if output_size > self.max_output_bytes:
            raise RuntimeError(f"SSH execution output exceeded {self.max_output_bytes} bytes.")

    def _collect_artifacts(

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Raise the provider-level timeout at initialize: config {'timeout': 300} — it is the hard cap for every command
  2. Pass an explicit per-call timeout <= provider timeout: execute_code(..., timeout=300)
  3. Move long-running work out of the sandbox or chunk it with checkpoints
  4. Catch TimeoutError and treat the result as failed (the channel is closed; output so far is lost)

Example fix

# before
provider.initialize({..., "timeout": 30})
provider.execute_code(inst, "import time; time.sleep(60)", "python", timeout=120)  # dies at 30s

# after
provider.initialize({..., "timeout": 300})
provider.execute_code(inst, "import time; time.sleep(60)", "python", timeout=120)
Defensive patterns

Strategy: try-catch

Validate before calling

effective_timeout = min(int(call_timeout or provider.timeout), provider.timeout)
if effective_timeout < expected_runtime_seconds:
    raise RuntimeError(f"provider timeout {effective_timeout}s below expected runtime; raise config timeout")

Try / catch

try:
    result = provider.execute_code(instance_id, code, language, timeout=90)
except TimeoutError:
    result = ExecutionResult(stdout="", stderr="execution timed out", exit_code=-1)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/1b447749e9f50f29. Report an issue: GitHub.