infiniflow/ragflow · error · TimeoutError

Execution timed out after {exec_timeout} seconds

Error message

Execution timed out after {exec_timeout} seconds

What it means

Raised as TimeoutError by LocalSandboxProvider when the child process does not finish within exec_timeout (the minimum of the requested timeout and the provider's configured max). On POSIX the whole process group is SIGKILLed via killpg (children spawned with start_new_session), then remaining output is drained before raising.

Source

Thrown at agent/sandbox/providers/local.py:149

            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            encoding="utf-8",
            errors="replace",
            env=self._build_child_env(instance_dir),
            preexec_fn=self._limit_child_process if os.name == "posix" else None,
            start_new_session=os.name == "posix",
        )

        try:
            stdout, stderr = process.communicate(timeout=exec_timeout)
        except subprocess.TimeoutExpired:
            if os.name == "posix":
                os.killpg(process.pid, signal.SIGKILL)
            else:
                process.kill()
            process.communicate()
            raise TimeoutError(f"Execution timed out after {exec_timeout} seconds")

        execution_time = time.time() - start_time
        self._validate_output_size(stdout, stderr)
        stdout, structured_result = extract_structured_result(stdout)

        return ExecutionResult(
            stdout=stdout,
            stderr=stderr,
            exit_code=process.returncode,
            execution_time=execution_time,
            metadata={
                "instance_id": instance_id,
                "language": normalized_lang,
                "script_path": str(script_path),
                "status": "ok" if process.returncode == 0 else "error",
                "timeout": exec_timeout,
                "artifacts": self._collect_artifacts(instance_dir / "artifacts"),
                "result_present": structured_result.get("present", False),

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Fix or bound the sandboxed code — add internal timeouts to loops and network calls.
  2. Raise the requested timeout and the provider's configured timeout if the workload legitimately needs longer.
  3. Split long work into multiple execute_code calls, persisting intermediate state in artifacts.
  4. Note the process group is killed, so child processes do not keep the slot busy — the timeout reflects real wall time.

Example fix

# before
result = provider.execute_code(instance_id, code, "python", timeout=5)  # code sleeps 30s -> TimeoutError

# after: align the timeout with the workload (still capped by provider config)
result = provider.execute_code(instance_id, code, "python", timeout=60)
Defensive patterns

Strategy: try-catch

Validate before calling

# Static check on the code string for common unbounded patterns before paying for a run
import re
if re.search(r"while\s+True", code) and "break" not in code:
    raise ValueError("Refusing to run unbounded loop without break")

Try / catch

try:
    result = provider.execute_code(instance_id, code, "python", timeout=10)
except TimeoutError:
    logger.warning("Sandbox execution hit timeout; instance may hold partial state")
    provider.destroy_instance(instance_id)
    instance = provider.create_instance("python")
    raise

Prevention

When it happens

Trigger: User code containing infinite loops, deadlocks, or waits longer than exec_timeout; requesting a timeout larger than the provider max (it is clamped down); subprocesses spawned by the user code keeping the pipe open.

Common situations: Agent-generated code with unbounded loops; network calls without timeouts inside sandboxed code; forgetting that the provider-level `timeout` config caps every execution.

Understand the failure class

Related errors


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