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

Assignees

No one assigned

    Labels

    pythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowtriageUsage: [Issues], Target: All issues that still need to be triaged

    Type

    No fields configured for Bug.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions