langchain-ai/deepagents · error · ValueError

timeout must be positive, got {effective_timeout}

Error message

timeout must be positive, got {effective_timeout}

What it means

execute validates the effective timeout — the explicit argument, or the backend's default_timeout when None — and raises ValueError if it is not positive. Unlike the constructor check, this one fires per call, so a bad per-call timeout triggers it even on a correctly constructed backend.

Source

Thrown at libs/deepagents/deepagents/backends/local_shell.py:301

            # Override timeout for long-running commands
            result = backend.execute("make build", timeout=300)

            # Commands run in root_dir, but can access any path
            result = backend.execute("cat /etc/passwd")  # Can read system files!
            ```
        """
        if not command or not isinstance(command, str):
            return ExecuteResponse(
                output="Error: Command must be a non-empty string.",
                exit_code=1,
                truncated=False,
            )

        effective_timeout = timeout if timeout is not None else self._default_timeout
        if effective_timeout <= 0:
            msg = f"timeout must be positive, got {effective_timeout}"
            raise ValueError(msg)

        try:
            result = subprocess.run(  # noqa: S602
                command,
                check=False,
                shell=True,  # Intentional: designed for LLM-controlled shell execution
                capture_output=True,
                stdin=subprocess.DEVNULL,  # Prevent hanging on commands that read stdin (e.g. python, cat)
                text=True,
                timeout=effective_timeout,
                env=self._env,
                cwd=str(self.cwd),  # Use the root_dir from FilesystemBackend
                start_new_session=(sys.platform != "win32"),
            )

            # Combine stdout and stderr
            # Prefix each stderr line with [stderr] for clear attribution.
            # Example: "hello\n[stderr] error: file not found"  # noqa: ERA001

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass a positive timeout to execute, e.g. execute(cmd, timeout=30)
  2. Clamp computed budgets: timeout=max(1.0, remaining)
  3. Recheck the instance's default_timeout if relying on the default path
  4. Validate user-provided timeout values at your API boundary before forwarding

Example fix

// before
shell.execute(cmd, timeout=deadline - time.monotonic())
// after
shell.execute(cmd, timeout=max(1.0, deadline - time.monotonic()))
Defensive patterns

Strategy: validation

Validate before calling

timeout = explicit_timeout if explicit_timeout is not None else shell._default_timeout
if timeout <= 0:
    timeout = DEFAULT_CMD_TIMEOUT
shell.execute(cmd, timeout=timeout)

Try / catch

try:
    result = shell.execute(cmd, timeout=t)
except ValueError as exc:
    if "timeout must be positive" in str(exc):
        result = shell.execute(cmd, timeout=30)
    else:
        raise

Prevention

When it happens

Trigger: Calling execute(command, timeout=0) or timeout=-5, or execute(command, timeout=None) on an instance whose default_timeout ended up non-positive.

Common situations: Dynamic timeouts computed from a remaining-time budget that already hit zero, or passing user-supplied timeout values through unvalidated.

Understand the failure class

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/8586f2bc54029a5a. Report an issue: GitHub.