{"record":{"id":"bc7537fad56f4238","repo":"OpenBMB/ChatDev","slug":"max-iterations-must-be-an-integer","errorCode":null,"errorMessage":"max_iterations must be an integer","messagePattern":"max_iterations must be an integer","errorType":"validation","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"entity/configs/node/loop_counter.py","lineNumber":31,"sourceCode":")\n\n\n@dataclass\nclass LoopCounterConfig(BaseConfig):\n    \"\"\"Configuration schema for the loop counter node type.\"\"\"\n\n    max_iterations: int = 10\n    reset_on_emit: bool = True\n    message: Optional[str] = None\n\n    @classmethod\n    def from_dict(cls, data: Mapping[str, Any] | None, *, path: str) -> \"LoopCounterConfig\":\n        mapping = require_mapping(data or {}, path)\n        max_iterations_raw = mapping.get(\"max_iterations\", 10)\n        try:\n            max_iterations = int(max_iterations_raw)\n        except (TypeError, ValueError) as exc:  # pragma: no cover - defensive\n            raise ConfigError(\n                \"max_iterations must be an integer\",\n                extend_path(path, \"max_iterations\"),\n            ) from exc\n\n        if max_iterations < 1:\n            raise ConfigError(\"max_iterations must be >= 1\", extend_path(path, \"max_iterations\"))\n\n        reset_on_emit = bool(mapping.get(\"reset_on_emit\", True))\n        message = optional_str(mapping, \"message\", path)\n\n        return cls(\n            max_iterations=max_iterations,\n            reset_on_emit=reset_on_emit,\n            message=message,\n            path=path,\n        )\n\n    def validate(self) -> None:","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/entity/configs/node/loop_counter.py#L13-L49","documentation":"LoopCounterConfig.from_dict could not coerce the 'max_iterations' value (default 10) to int. Strings like 'ten', None, or lists raise TypeError/ValueError in int() and are reported as a config error.","triggerScenarios":"Passing max_iterations as a non-numeric string, null, or a list/dict. Note numeric strings like '5' DO parse because int() accepts them, so only truly non-numeric values fail.","commonSituations":"YAML value left blank (null); env-var injection of an empty string; prose values pasted instead of numbers.","solutions":["Set max_iterations to an integer, e.g. 10","Use a numeric string only if unavoidable ('5' works, but prefer int)","If sourcing from env, wrap: int(os.environ.get('MAX_ITER', '10')) with try/except and a clear message"],"exampleFix":"# before\n{\"max_iterations\": \"ten\"}\n# after\n{\"max_iterations\": 10}","handlingStrategy":"validation","validationCode":"raw = data.get('max_iterations', 10)\ntry:\n    data['max_iterations'] = int(raw)\nexcept (TypeError, ValueError):\n    data['max_iterations'] = 10","typeGuard":"def coercion_safe(data: dict) -> bool:\n    try:\n        int(data.get('max_iterations', 10))\n        return True\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    LoopCounterConfig.from_dict(data, path='lc')\nexcept ConfigError as e:\n    if 'max_iterations' in e.path:\n        data['max_iterations'] = 10\n        LoopCounterConfig.from_dict(data, path='lc')\n    else:\n        raise","preventionTips":["Always emit ints from config generators","int() env-derived values at load time with a default","Avoid blank YAML values (they become None)"],"tags":["config","loop","validation","python"],"backgroundTag":"type-coercion-failed","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}