Skip to content

Python: [Bug]: Raise a clear handler registration error for unresolved TypeVar #4943

@moonbox3

Description

@moonbox3

Description

Follow-up from #4534 and this comment:
#4534 (comment)

Today, class-based @handler registration accepts unresolved TypeVar annotations and stores them in the handler spec. The actual failure then shows up later during workflow edge validation as a TypeCompatibilityError against a downstream executor, which points users in the wrong direction.

We should detect unresolved TypeVar usage earlier, during handler registration, and raise a clearer error that explains the real issue:

  • the handler did not resolve to concrete runtime types
  • generic TypeVar annotations are not supported for workflow type validation in this path
  • users should use explicit decorator types such as @handler(input=..., output=..., workflow_output=...) when the concrete message type is only known in a factory

Expected behavior:

  • unresolved TypeVar in the message annotation or WorkflowContext[...] generics should fail at registration time
  • the error should explicitly recommend @handler(input=..., output=...) instead of letting the workflow build continue to a confusing TypeCompatibilityError

Likely scope:

  • packages/core/agent_framework/_workflows/_executor.py
  • possibly parity in packages/core/agent_framework/_workflows/_function_executor.py
  • regression tests in packages/core/tests/workflow/

Code Sample

from typing import Generic, TypeVar

from agent_framework import Executor, WorkflowBuilder, WorkflowContext, handler

T = TypeVar("T")


class EchoExecutor(Executor, Generic[T]):
    @handler
    async def echo(self, message: T, ctx: WorkflowContext[T]) -> None:
        await ctx.send_message(message)


class PageContent:
    pass


class SinkExecutor(Executor):
    @handler
    async def handle(self, message: PageContent, ctx: WorkflowContext) -> None:
        pass


start = EchoExecutor[PageContent](id="start")
sink = SinkExecutor(id="sink")

WorkflowBuilder(start_executor=start).add_edge(start, sink).build()

Error Messages / Stack Traces

Current behavior is that registration succeeds, and workflow validation later fails with a
TypeCompatibilityError against the downstream executor instead of a clearer registration-time
error about unresolved TypeVar usage.

Package Versions

agent-framework-core: current main (follow-up from issue #4534, originally reported with agent-framework-azure-ai==1.0.0rc3)

Python Version

Python 3.11+

Additional Context

This is the follow-up action item promised in #4534 after clarifying that the supported workaround is:

@handler(input=message_type, output=message_type)

The goal is not to add generic TypeVar support here, but to fail fast with an actionable error message when unresolved TypeVar reaches handler registration.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpython

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions