{"record":{"id":"49832ba116914a5a","repo":"agentscope-ai/agentscope","slug":"invalid-inputs-with-reply-id-inputs-reply-id","errorCode":null,"errorMessage":"Invalid inputs with reply_id: {inputs.reply_id}. ","messagePattern":"Invalid inputs with reply_id: (.+?)\\. ","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/pipeline/_goal_pipeline.py","lineNumber":159,"sourceCode":"                    self._goal.extend(_.content)\n                executor_inputs.append(\n                    UserMsg(\"system\", content=hint),\n                )\n\n        elif isinstance(\n            inputs,\n            (\n                UserConfirmResultEvent,\n                UserInterruptEvent,\n                ExternalExecutionResultEvent,\n            ),\n        ):\n            if inputs.reply_id == self.executor.state.reply_id:\n                executor_inputs = inputs\n            elif inputs.reply_id == self.verifier.state.reply_id:\n                verifier_inputs = inputs\n            else:\n                raise ValueError(\n                    f\"Invalid inputs with reply_id: {inputs.reply_id}. \",\n                )\n\n        if isinstance(inputs, UserInterruptEvent):\n            parked = (\n                self.verifier if verifier_inputs is not None else self.executor\n            )\n            async for _ in parked.reply_stream(inputs=inputs):\n                yield _\n            return\n\n        # Start the pipeline loop\n        while True:\n            # Executor step\n            break_loop = False\n            execution_report = None\n            if executor_inputs is not None:\n                while execution_report is None:","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/pipeline/_goal_pipeline.py#L141-L177","documentation":"GoalPipeline.reply_stream routes incoming events by matching inputs.reply_id against the executor's or verifier's state reply_id. An event whose reply_id matches neither is rejected as invalid — it belongs to a different/unknown reply thread.","triggerScenarios":"Feeding an event carrying a stale or foreign reply_id into reply_stream, e.g. reusing an event from a previous pipeline run or from another conversation after the pipeline's state was reset.","commonSituations":"Replaying recorded events; sharing a pipeline across sessions; resuming after interrupt where the state got a new reply_id but queued old events are still fed in.","solutions":["Regenerate the input event via pipeline.new_reply()/the API that assigns the current reply_id instead of reusing old events","Track the current reply_id and drop/refresh events whose id doesn't match before calling reply_stream","Reset the pipeline consistently when starting a new conversation so state and events stay in sync"],"exampleFix":"# before\nasync for ev in pipeline.reply_stream(old_event):  # stale reply_id\n    ...\n\n# after\nevent = await pipeline.new_reply(...)  # fresh reply_id\nasync for ev in pipeline.reply_stream(event):\n    ...","handlingStrategy":"validation","validationCode":"current_ids = {pipeline.executor.state.reply_id, pipeline.verifier.state.reply_id}\nif getattr(inputs, 'reply_id', None) not in current_ids:\n    inputs = await pipeline.new_reply(inputs.content)  # refresh id","typeGuard":"def event_matches_pipeline(event, pipeline) -> bool:\n    return event.reply_id in (pipeline.executor.state.reply_id, pipeline.verifier.state.reply_id)","tryCatchPattern":null,"preventionTips":["Never replay events from prior runs; regenerate them","Reset pipeline and event buffers together when starting new conversations"],"tags":["agentscope","pipeline","reply-id","event-routing"],"backgroundTag":"stale-session-id","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}