agentscope-ai/agentscope · error · RuntimeError
{type(self).__name__} does not implement on_reply
Error message
{type(self).__name__} does not implement on_reply What it means
Middleware.on_reply is an optional override point: the base class implementation raises RuntimeError if invoked. A middleware that does not implement on_reply was placed into a reply-related hook chain, and the chain dispatched to the base stub.
Source
Thrown at src/agentscope/middleware/_base.py:96
``Msg`` is only produced once the event escapes the whole chain.
When swallowing an exceed-max-iters end, unblock the next round
first (e.g. adjust ``cur_iter`` or ``max_iters``). Interrupted
ends cannot be swallowed to continue the reply.
Args:
agent: The Agent instance executing this middleware
input_kwargs: Dictionary containing:
- inputs: Msg | list[Msg] | UserConfirmResultEvent |
ExternalExecutionResultEvent | None — the unified inputs
that trigger this reply (new message(s), a resumption
event from a previous outside interaction, or None).
next_handler: Callable that executes the next middleware or
original method
Yields:
AgentEvent | Msg: Events from the reply process
"""
raise RuntimeError(
f"{type(self).__name__} does not implement on_reply",
)
yield # pylint: disable=unreachable
async def on_reasoning(
self,
agent: "Agent",
input_kwargs: dict,
next_handler: Callable[..., AsyncGenerator],
) -> AsyncGenerator:
"""Hook for intercepting the reasoning process.
Args:
agent: The Agent instance executing this middleware
input_kwargs: Dictionary containing:
- tool_choice: ToolChoice (default None)
next_handler: Callable that executes the next middleware or
original methodView on GitHub (pinned to e90f1c7592)
Solutions
- Implement async on_reply(self, agent, reply, next_handler) in your middleware, typically delegating via next_handler when passthrough behavior is desired
- If the hook is genuinely not needed, remove the middleware from the chain that invokes on_reply
- Ensure you don't call super().on_reply() in your override
Example fix
// before
class MyMiddleware(Middleware):
async def on_acting(self, agent, tool_call, next_handler):
...
# registered in a chain that calls on_reply -> RuntimeError 233
// after
class MyMiddleware(Middleware):
async def on_reply(self, agent, reply, next_handler):
# passthrough
async for ev in next_handler(reply):
yield ev
async def on_acting(self, agent, tool_call, next_handler):
... Defensive patterns
Strategy: type-guard
Validate before calling
from agentscope.middleware import Middleware
assert type(mw).on_reply is not Middleware.on_reply, f"{type(mw).__name__} lacks on_reply" Type guard
def implements_on_reply(mw) -> bool:
from agentscope.middleware import Middleware
return type(mw).on_reply is not Middleware.on_reply Prevention
- Always implement required-chain hooks, defaulting to passthrough via next_handler
- Write a registration helper that checks which hooks each middleware implements
- Never call super().on_reply() in overrides
When it happens
Trigger: Registering a middleware that only implements, say, on_acting, in a position where the framework calls on_reply on it (e.g. wrapping the agent's reply method with a middleware chain that requires on_reply), or calling super().on_reply(...) without overriding.
Common situations: Copying a middleware subclass template and deleting the method you thought was unused; middleware base classes where some hooks are optional per the docs but the specific chain requires them; calling next_handler incorrectly so control falls to the base stub.
Related errors
- {type(self).__name__} does not implement on_reasoning
- {type(self).__name__} does not implement on_acting
- f"{type(self).__name__} does not implement on_check_permissi
- f"{type(self).__name__} does not implement on_model_call"
- f"{type(self).__name__} does not implement on_compress_conte
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/994b8f0dfacf144b.
Report an issue: GitHub.