Skip to content

Python: [Bug]: @response_handler fails with postponed annotations #8327

Closed

Description

@CoralGarden52

Description

The introspection mode of @response_handler reads raw values from inspect.signature(func). When a module uses from __future__ import annotations, valid request, response, and WorkflowContext[...] annotations are stored as strings, but the response-handler validation path does not resolve them before validating the context annotation.

This causes a valid executor definition to fail while the class body is being evaluated, so the executor cannot be imported or instantiated.

Reproduction

from __future__ import annotations

from agent_framework import Executor, WorkflowContext, handler, response_handler

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

    @response_handler
    async def handle_response(
        self, original_request: str, response: int, ctx: WorkflowContext[str]
    ) -> None:
        pass

On the current upstream main, defining the class raises:

ValueError: Response handler parameter 'ctx' must be annotated as WorkflowContext, WorkflowContext[T], or WorkflowContext[T, U], got WorkflowContext[str]

Expected behavior

The introspection path should resolve postponed annotations in the same way as the existing @handler path, then register the response handler with str as the request type, int as the response type, and str as the workflow output type.

Scope

This affects introspection mode only. Explicit @response_handler(request=..., response=...) parameters already resolve string references and should remain unchanged.

The corresponding @handler future-annotation behavior is covered by test_executor_future.py (issue #3898); this issue tracks the missing response-handler counterpart.

Activity

  1. added
    pythonUsage: [Issues, PRs], Target: Python
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Sep 12, 2026
  2. added
    reproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
    on Sep 12, 2026
  3. github-actions commented on Sep 12, 2026

    @github-actions
    Contributor

    🤖 Automated triage reproduction notes (agent-authored — trust but verify)

    Agent analysis

    The bug occurs in python/packages/core/agent_framework/_workflows/_request_info_mixin.py::_validate_response_handler_signature at lines 325-366. It is triggered when introspection-mode @response_handler receives postponed request, response, and WorkflowContext annotations, causing the raw context string to fail validation. Minimal repro: define the issue’s executor under from __future__ import annotations; class definition raises before instantiation.

    • Failing test: python/packages/core/tests/workflow/test_executor_future.py
    • Files examined: python/packages/core/agent_framework/_workflows/_request_info_mixin.py, python/packages/core/agent_framework/_workflows/_workflow_context.py, python/packages/core/agent_framework/_workflows/_executor.py, python/packages/core/tests/workflow/test_executor_future.py, python/packages/core/tests/workflow/test_executor.py, python/packages/core/pyproject.toml
    • Tests run: test_response_handler_decorator_future_annotations, test_handler_decorator_future_annotations, test_executor_output_types_includes_response_handlers
    • Current version: 1.18.0
  4. added
    workflowsUsage: [Issues, PRs], Target: Workflows
    and removed
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Sep 12, 2026
  5. he-yufeng commented on Sep 13, 2026

    @he-yufeng
    Contributor

    The mechanism is exactly as analyzed: the @handler path resolves postponed annotations through typing.get_type_hints, while _validate_response_handler_signature reads raw inspect.signature annotations, so under from __future__ import annotations the ctx string "WorkflowContext[str]" reaches validate_workflow_context_annotation unresolved and a valid executor definition raises during class evaluation.

    Fix mirrors the decorator's explicit-parameter path: resolve each annotation with the existing resolve_type_annotation helper against func.__globals__, falling back to the raw annotation when resolution fails so registration failures stay diagnosable. Verified with the issue's repro (red before, green after) plus response-handler counterparts of the test_executor_future.py cases.

    I have the patch ready and will open a PR shortly unless you'd rather take it yourself, Eduard van Valkenburg (@eavanvalkenburg).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

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

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions