Skip to content

Python: [Bug]: Callable class middleware raises AttributeError instead of MiddlewareException when __call__ has fewer than 2 parameters #6697

Description

@PreethamNoelP

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:

  1. Create a callable class whose __call__ takes only 1 parameter (missing call_next)
  2. Pass an instance to Agent(..., middleware=[BadMiddleware()])
  3. 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.

Metadata

Metadata

Labels

pythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

Type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions