infiniflow/ragflow · warning · RuntimeError

Execution timeout must be greater than 0 seconds, got {reque

Error message

Execution timeout must be greater than 0 seconds, got {requested_timeout}.

What it means

Raised by SSHProvider.execute_code when the effective execution timeout resolves to zero or a negative number. The effective value is int(timeout) if the caller passes one, otherwise the provider-level self.timeout (default 30, set from config). It is a pure input-validation guard fired before any SSH traffic, though it raises RuntimeError rather than ValueError.

Source

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

        normalized_lang = self._normalize_language(language)
        instance = self._instances[instance_id]
        client: paramiko.SSHClient = instance["client"]
        sftp: paramiko.SFTPClient = instance["sftp"]
        remote_work_dir: str = instance["remote_work_dir"]

        args_json = json.dumps(arguments or {}, ensure_ascii=False)
        remote_script_path, command = self._upload_script(
            sftp=sftp,
            remote_work_dir=remote_work_dir,
            language=normalized_lang,
            code=code,
            args_json=args_json,
        )

        requested_timeout = self.timeout if timeout is None else int(timeout)
        if requested_timeout <= 0:
            raise RuntimeError(f"Execution timeout must be greater than 0 seconds, got {requested_timeout}.")
        exec_timeout = min(requested_timeout, self.timeout)

        start_time = time.time()
        stdout, stderr, exit_code = self._run_remote_command(client, command, timeout=exec_timeout)
        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=exit_code,
            execution_time=execution_time,
            metadata={
                "instance_id": instance_id,
                "language": normalized_lang,
                "script_path": remote_script_path,

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Pass a positive timeout (e.g. 30) to execute_code, or omit it to use the provider default
  2. If your config sets timeout=0 intending 'no limit', set a large finite value instead — the provider clamps exec_timeout to min(requested, self.timeout) anyway
  3. Clamp computed deadlines: timeout=max(1, int(remaining)) before calling

Example fix

// before
result = provider.execute_code(instance_id, code, "python", timeout=0)

// after
result = provider.execute_code(instance_id, code, "python", timeout=30)
Defensive patterns

Strategy: validation

Validate before calling

timeout = int(timeout) if timeout is not None else provider.timeout
if timeout <= 0:
    timeout = 30
result = provider.execute_code(instance_id, code, language, timeout=timeout)

Type guard

def is_valid_timeout(t) -> bool:
    try:
        return int(t) > 0
    except (TypeError, ValueError):
        return False

Prevention

When it happens

Trigger: Calling execute_code(..., timeout=0) or timeout=-5; passing timeout=None while the provider was initialized with config timeout=0 (initialize does not reject non-positive timeouts); passing a numeric string like "0" that int() coerces to 0.

Common situations: Configuring agent/component timeouts with 0 meaning 'no limit' (this provider treats 0 as invalid, not unlimited); per-call timeout derived from a remaining-deadline computation that hits 0 on retry; copy-pasting defaults from another provider that accepts 0.

Understand the failure class

Related errors


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