langchain-ai/deepagents · error · ValueError

timeout must be positive, got {timeout}

Error message

timeout must be positive, got {timeout}

What it means

LocalShellBackend's constructor requires a strictly positive timeout (in seconds) for command execution and raises ValueError otherwise. A non-positive timeout would make every subprocess.run call invalid, so the backend refuses construction.

Source

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

            env: Environment variables for shell commands.

                If `None`, starts with an empty environment
                (unless `inherit_env=True`).

            inherit_env: Whether to inherit the parent process's environment variables.

                When `False` (default), only variables in `env` dict are available.

                When `True`, inherits all `os.environ` variables
                and applies `env` overrides.

        Raises:
            ValueError: If timeout is not positive.
        """
        if timeout <= 0:
            msg = f"timeout must be positive, got {timeout}"
            raise ValueError(msg)

        # Initialize parent FilesystemBackend
        super().__init__(
            root_dir=root_dir,
            virtual_mode=virtual_mode,
            max_file_size_mb=10,
        )

        # Store execution parameters
        self._default_timeout = timeout
        self._max_output_bytes = max_output_bytes

        # Build environment based on inherit_env setting
        if inherit_env:
            self._env = os.environ.copy()
            if env is not None:
                self._env.update(env)
        else:

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass a positive timeout, e.g. timeout=30
  2. Fix config loading so an unset timeout falls back to a positive default instead of 0
  3. Guard computed deadlines: use max(some_minimum, remaining_time)
  4. Omit the argument to use the class's built-in default if you have no preference

Example fix

// before
backend = LocalShellBackend(root_dir=cfg.root, timeout=cfg.get("timeout", 0))
// after
backend = LocalShellBackend(root_dir=cfg.root, timeout=cfg.get("timeout", 30))
Defensive patterns

Strategy: validation

Validate before calling

timeout = cfg.get("timeout") or DEFAULT_TIMEOUT
if timeout <= 0:
    raise ValueError(f"configured timeout must be positive, got {timeout}")
backend = LocalShellBackend(root_dir=root, timeout=timeout)

Try / catch

try:
    backend = LocalShellBackend(root_dir=root, timeout=cfg_timeout)
except ValueError as exc:
    if "timeout must be positive" in str(exc):
        backend = LocalShellBackend(root_dir=root)  # fall back to default
    else:
        raise

Prevention

When it happens

Trigger: LocalShellBackend(root_dir=..., timeout=0) or timeout=-1, often from a config value defaulting to 0 (unset) or a computed value like deadline - now that reached zero.

Common situations: Config files where timeout is unset and coerces to 0, parsing durations as ints and losing fractions, or an expired deadline being passed through.

Understand the failure class

Related errors


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