Repository navigation
Description
Description
An executor that declares WorkflowContext[Any] reports Any as its output type. Edge validation runs is_type_compatible(source_type, target_type), which only special-cases Any as the target:
# Case 0: target_type is Any - always compatible
if target_type is Any:
return TrueThere is no matching case for an Any source, so is_type_compatible(Any, str) is False and the edge is rejected. Any means the value can be of any type, so it should be accepted in both directions, the way type checkers treat it.
Reproduction
from typing import Any
from agent_framework import Executor, WorkflowBuilder, WorkflowContext, handler
class Source(Executor):
@handler
async def run(self, text: str, ctx: WorkflowContext[Any]) -> None:
await ctx.send_message(text)
class Target(Executor):
@handler
async def run(self, text: str, ctx: WorkflowContext[Any]) -> None:
print("target got", text)
src, tgt = Source(id="a"), Target(id="b")
WorkflowBuilder(start_executor=src).add_edge(src, tgt).build()Actual:
TypeCompatibilityError: [TYPE_COMPATIBILITY] Type incompatibility between executors 'a' -> 'b'. Source executor outputs types ['typing.Any'] but target executor can only handle types ["<class 'str'>"].
Direct check:
>>> is_type_compatible(str, Any)
True
>>> is_type_compatible(Any, str)
FalseExpected behavior
The workflow builds. An executor that may send any type should be allowed to feed a typed executor, just as WorkflowContext without a type parameter is (that path passes because the output type list is empty).
The same asymmetry affects nested types, e.g. list[Any] -> list[str], and the fan-in path, which wraps the source type in list[...].
Environment
- agent-framework-core: main (02bd1ba)
- Python 3.13
Metadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
github-actions commentedon Sep 22, 2026
🤖 Automated triage reproduction notes (agent-authored — trust but verify)
Agent analysis
python/packages/core/agent_framework/_workflows/_typing_utils.py::is_type_compatiblereturns false whentyping.Anyis the source and a concrete type is the target, causing_validation.py::_validate_edge_type_compatibilityto reject the edge; recursive checks also rejectlist[Any]used by fan-in. Minimal repro: connect a source usingWorkflowContext[Any]to a target acceptingstrand callWorkflowBuilder.build(); the added focused test fails withTypeCompatibilityError.python/packages/core/tests/workflow/test_validation.py::test_type_compatibility_with_any_output_type_passes1.19.0