OpenBMB/ChatDev · error · ConfigError

max_iterations must be >= 1

Error message

max_iterations must be >= 1

What it means

LoopCounterConfig.from_dict rejects a max_iterations value that coerces to an integer below 1. A loop counter that never iterates is meaningless, so zero and negatives are config errors.

Source

Thrown at entity/configs/node/loop_counter.py:37

    max_iterations: int = 10
    reset_on_emit: bool = True
    message: Optional[str] = None

    @classmethod
    def from_dict(cls, data: Mapping[str, Any] | None, *, path: str) -> "LoopCounterConfig":
        mapping = require_mapping(data or {}, path)
        max_iterations_raw = mapping.get("max_iterations", 10)
        try:
            max_iterations = int(max_iterations_raw)
        except (TypeError, ValueError) as exc:  # pragma: no cover - defensive
            raise ConfigError(
                "max_iterations must be an integer",
                extend_path(path, "max_iterations"),
            ) from exc

        if max_iterations < 1:
            raise ConfigError("max_iterations must be >= 1", extend_path(path, "max_iterations"))

        reset_on_emit = bool(mapping.get("reset_on_emit", True))
        message = optional_str(mapping, "message", path)

        return cls(
            max_iterations=max_iterations,
            reset_on_emit=reset_on_emit,
            message=message,
            path=path,
        )

    def validate(self) -> None:
        if self.max_iterations < 1:
            raise ConfigError("max_iterations must be >= 1", extend_path(self.path, "max_iterations"))

    FIELD_SPECS = {
        "max_iterations": ConfigFieldSpec(
            name="max_iterations",

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Set max_iterations to at least 1
  2. To 'disable' the loop, remove the counter from the graph or gate execution elsewhere
  3. Compute bounds with max(1, computed_value) when derived from variables

Example fix

# before
{"max_iterations": 0}
# after
{"max_iterations": 1}
Defensive patterns

Strategy: validation

Validate before calling

n = int(data.get('max_iterations', 10))
if n < 1:
    data['max_iterations'] = 1

Type guard

def iterations_in_range(data: dict) -> bool:
    try:
        return int(data.get('max_iterations', 10)) >= 1
    except (TypeError, ValueError):
        return False

Try / catch

try:
    LoopCounterConfig.from_dict(data, path='lc')
except ConfigError as e:
    if '>= 1' in str(e):
        data['max_iterations'] = 1
        LoopCounterConfig.from_dict(data, path='lc')
    else:
        raise

Prevention

When it happens

Trigger: Passing max_iterations: 0, a negative number, or a numeric string like '0'/'-3' that int() happily converts before the range check.

Common situations: Disabling a loop by setting iterations to 0 (use node removal or a bypass instead); arithmetic that computes a zero/negative bound.

Related errors


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