{"record":{"id":"f91977441343bce0","repo":"OpenBMB/ChatDev","slug":"node-node-id-missing-loop-timer-configuration","errorCode":null,"errorMessage":"Node {node.id} missing loop_timer configuration","messagePattern":"Node (.+?) missing loop_timer configuration","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"runtime/node/executor/loop_timer_executor.py","lineNumber":28,"sourceCode":"\n\nclass LoopTimerNodeExecutor(NodeExecutor):\n    \"\"\"Track loop duration and emit output only after hitting the time limit.\n\n    Supports two modes:\n    1. Standard Mode (passthrough=False): Suppresses input until time limit, then emits message\n    2. Terminal Gate Mode (passthrough=True): Acts as a sequential switch\n       - Before limit: Pass input through unchanged\n       - At limit: Emit configured message, suppress original input\n       - After limit: Transparent gate, pass all subsequent messages through\n    \"\"\"\n\n    STATE_KEY = \"loop_timer\"\n\n    def execute(self, node: Node, inputs: List[Message]) -> List[Message]:\n        config = node.as_config(LoopTimerConfig)\n        if config is None:\n            raise ValueError(f\"Node {node.id} missing loop_timer configuration\")\n\n        state = self._get_state()\n        timer_state = state.setdefault(node.id, {})\n\n        # Initialize timer on first execution\n        current_time = time.time()\n        if \"start_time\" not in timer_state:\n            timer_state[\"start_time\"] = current_time\n            timer_state[\"emitted\"] = False\n\n        start_time = timer_state[\"start_time\"]\n        elapsed_time = current_time - start_time\n\n        # Convert max_duration to seconds based on unit\n        max_duration_seconds = self._convert_to_seconds(\n            config.max_duration, config.duration_unit\n        )\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/runtime/node/executor/loop_timer_executor.py#L10-L46","documentation":"LoopTimerNodeExecutor requires a LoopTimerConfig; without it there is no duration/timeout to enforce, so execution fails fast instead of defaulting silently.","triggerScenarios":"Executing a loop_timer node whose as_config(LoopTimerConfig) is None.","commonSituations":"Workflow definitions authored without the timer config; version drift renaming timer fields; tests omitting config.","solutions":["Add a LoopTimerConfig (e.g. duration seconds / max wait) to the node","Schema-validate workflows containing loop_timer nodes","Migrate old workflow files after runtime upgrades"],"exampleFix":"# before\nNode(id='t1', node_type='loop_timer')\n\n# after\nNode(id='t1', node_type='loop_timer', config={'duration_seconds': 30})","handlingStrategy":"validation","validationCode":"assert node.as_config(LoopTimerConfig) is not None","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add config schema checks in CI for workflow fixtures"],"tags":["loop-timer","missing-config"],"backgroundTag":"missing-node-config","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}