Description
What happened?
Passing a callable class instance (a class with __call__ but fewer than 2 parameters) as middleware raises:
AttributeError: 'BadMiddleware' object has no attribute '__name__'
The error gives zero indication of what the user did wrong.
What did you expect to happen?
A clear MiddlewareException:
"Middleware function must have at least 2 parameters (context, call_next), but BadMiddleware has 1."
Steps to reproduce:
- Create a callable class whose
__call__ takes only 1 parameter (missing call_next)
- Pass an instance to
Agent(..., middleware=[BadMiddleware()])
- Constructor raises
AttributeError instead of MiddlewareException
Code Sample
from unittest.mock import AsyncMock
from agent_framework import Agent
class BadMiddleware:
async def __call__(self, ctx): # missing `call_next` second parameter
pass
agent = Agent(client=AsyncMock(), middleware=[BadMiddleware()])
Error Messages / Stack Traces
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../agent_framework/_middleware.py", line 1263, in __init__
middleware_list = categorize_middleware(middleware)
...
File ".../agent_framework/_middleware.py", line 1501, in _determine_middleware_type
f"Cannot determine middleware type for function {middleware.__name__}. "
AttributeError: 'BadMiddleware' object has no attribute '__name__'
Package Versions
agent-framework-core: 1.9.0
Python Version
Python 3.10 – 3.14 (all versions affected)
Additional Context
Root Cause:
_determine_middleware_type() in _middleware.py uses middleware.__name__ bare at lines 1474, 1487, and 1501. Functions/lambdas always have __name__, but callable class instances do not — instance.__name__ raises AttributeError. The first occurrence is silently swallowed by except Exception: pass, and the second (outside the try/except) propagates uncaught.
Proposed Fix (3 lines):
Replace middleware.__name__ with getattr(middleware, '__name__', type(middleware).__name__) at lines 1474, 1487, and 1501 in _middleware.py. Purely additive — no behaviour changes for existing working paths.
A regression test should be added to test_middleware_with_agent.py covering callable class instances with insufficient parameters.
Description
What happened?
Passing a callable class instance (a class with
__call__but fewer than 2 parameters) as middleware raises:AttributeError: 'BadMiddleware' object has no attribute '__name__'The error gives zero indication of what the user did wrong.
What did you expect to happen?
A clear
MiddlewareException:"Middleware function must have at least 2 parameters (context, call_next), but BadMiddleware has 1."
Steps to reproduce:
__call__takes only 1 parameter (missingcall_next)Agent(..., middleware=[BadMiddleware()])AttributeErrorinstead ofMiddlewareExceptionCode Sample
from unittest.mock import AsyncMock from agent_framework import Agent class BadMiddleware: async def __call__(self, ctx): # missing `call_next` second parameter pass agent = Agent(client=AsyncMock(), middleware=[BadMiddleware()])Error Messages / Stack Traces
Package Versions
agent-framework-core: 1.9.0
Python Version
Python 3.10 – 3.14 (all versions affected)
Additional Context
Root Cause:
_determine_middleware_type()in_middleware.pyusesmiddleware.__name__bare at lines 1474, 1487, and 1501. Functions/lambdas always have__name__, but callable class instances do not —instance.__name__raises AttributeError. The first occurrence is silently swallowed byexcept Exception: pass, and the second (outside the try/except) propagates uncaught.Proposed Fix (3 lines):
Replace
middleware.__name__withgetattr(middleware, '__name__', type(middleware).__name__)at lines 1474, 1487, and 1501 in_middleware.py. Purely additive — no behaviour changes for existing working paths.A regression test should be added to
test_middleware_with_agent.pycovering callable class instances with insufficient parameters.