OpenBMB/ChatDev · error · ConfigError

timeout_seconds must be a positive integer

Error message

timeout_seconds must be a positive integer

What it means

PythonRunnerConfig.from_dict validates that 'timeout_seconds' (default 60) is an int greater than zero. Floats, strings, bools with value <= 0 paths, zero, or negatives raise this ConfigError at path '<path>.timeout_seconds'.

Source

Thrown at entity/configs/node/python_runner.py:39

@dataclass
class PythonRunnerConfig(BaseConfig):
    interpreter: str = field(default_factory=_default_interpreter)
    args: List[str] = field(default_factory=list)
    env: Dict[str, str] = field(default_factory=dict)
    timeout_seconds: int = 60
    encoding: str = "utf-8"

    @classmethod
    def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "PythonRunnerConfig":
        mapping = require_mapping(data, path)
        interpreter = optional_str(mapping, "interpreter", path) or _default_interpreter()
        args_raw = mapping.get("args")
        args = [str(item) for item in ensure_list(args_raw)] if args_raw is not None else []
        env = optional_dict(mapping, "env", path) or {}
        timeout_value = mapping.get("timeout_seconds", 60)
        if not isinstance(timeout_value, int) or timeout_value <= 0:
            raise ConfigError("timeout_seconds must be a positive integer", f"{path}.timeout_seconds")
        encoding = optional_str(mapping, "encoding", path) or "utf-8"
        if not encoding:
            raise ConfigError("encoding cannot be empty", f"{path}.encoding")
        return cls(
            interpreter=interpreter,
            args=args,
            env={str(key): str(value) for key, value in env.items()},
            timeout_seconds=timeout_value,
            encoding=encoding,
            path=path,
        )

    FIELD_SPECS = {
        "interpreter": ConfigFieldSpec(
            name="interpreter",
            display_name="Python Path",
            type_hint="str",
            required=False,

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Use a positive integer, e.g. 120
  2. Wrap computed timeouts with int(...) ensuring > 0
  3. For long runs set a large value rather than 0

Example fix

# before
timeout_seconds: 30.5
# after
timeout_seconds: 30
Defensive patterns

Strategy: validation

Validate before calling

t = cfg.get('timeout_seconds', 60)
assert isinstance(t, int) and not isinstance(t, bool) and t > 0

Type guard

def is_valid_timeout(v) -> bool:
    return isinstance(v, int) and not isinstance(v, bool) and v > 0

Try / catch

try:
    PythonRunnerConfig.from_dict(d, path='config')
except ConfigError as e:
    if 'timeout_seconds' in str(e):
        d['timeout_seconds'] = max(1, int(float(d['timeout_seconds'])))
        PythonRunnerConfig.from_dict(d, path='config')

Prevention

When it happens

Trigger: Setting timeout_seconds: 30.5, timeout_seconds: 0, or timeout_seconds: '60' in a python_runner node config.

Common situations: YAML floats from tuning (e.g. 0.5s granularity not supported); stringified values from env vars; setting 0 intending 'no timeout' — not allowed, pick a large int instead.

Understand the failure class

Related errors


AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27). Data as JSON: /api/errors/db5320e76f0f7d8d. Report an issue: GitHub.