Skip to content

Reject unsupported async workflow definitions before polling #106

Closed

Description

@rmcdaniel

Verified problem

A fresh consumer of Python SDK 2.5.0 accepts this workflow at production Worker registration:

@workflow.defn(name="async-example")
class Example:
    async def run(self, ctx):
        return "done"

replay(Example, [], []) returns a CompleteWorkflow whose result is an unawaited coroutine. The workflow body has not executed. This is an unsupported definition accepted as though it were a completed workflow.

Required outcome

  • Reject unsupported coroutine workflow entry points during definition/registration, before Server polling.
  • Provide a clear error identifying the workflow and the supported synchronous/generator authoring model.
  • Apply signature validation consistently in the production Worker and public test harness.
  • Cover coroutine functions and async-generator entry points, while preserving supported synchronous and generator workflows.
  • Never publish an unawaited coroutine as a workflow result.
  • Verify the published successor with an ordinary consumer.

This issue asks for clear rejection under the existing execution model. A new async workflow engine would require its own deliberate design.

Reproduced through published registration and replay APIs without network requests. Current main 04790ae42e8da0a83f65026f096572b547b7baa8 still contains the behavior.

Sources: production worker, replayer.

Activity

  1. rmcdaniel commented on Oct 10, 2026

    @rmcdaniel
    MemberAuthor

    PR #108 rejects coroutine and async-generator workflow entry points before worker polling. Definition, production Worker, the public test environment and direct replay share validation, including wrapped, inherited, callable-object and partial entry points.

    Synchronous and generator workflows also reject awaitable results with the typed InvalidWorkflowDefinition SDK error. Native coroutine results are closed. Supported synchronous/generator workflows and async activities keep their execution models.

    Ten original regressions fail against 2.5.1 and the valid control passes. The repaired focused suite and replay corpus pass 57 checks; Ruff and mypy pass. A new official replay fixture covers the previously accepted async entry point. Full main qualification passes, including Python 3.10/3.11/3.12, integration, the counterfactual gate and package checks.

    2.5.2 is published at exact source 39ae905cf1eb9bb949f98ddbe6458792ae3cd7af. Publication verification passes. A fresh PyPI wheel passes all 18 focused consumer checks, including supported synchronous/generator workflows and a supported async activity. Runtime and unraisable warnings are errors. Wheel SHA256: 35794a31b533637bec6aaac6aa85393b3b16eb64d2b015848fb6ed3fc4270d0c.

    Ordinary consumers are delivered through Website #199 and Sample App #189. The live website serves 2.5.2. All 18 sample PR checks and every main check pass. Actual published activity recovery passes 45 cases across all nine PHP/Python/Rust directions with Python 2.5.2 workers. Published image qualification passes on native amd64 and arm64 runners. Both public registries' main indexes match the qualified immutable image, digest sha256:296b67aa0eaed902b04502604d9378b0c0008e9aeef680cddc5db4f6e40950d2.

    The unsupported-entry-point and awaitable-result defects are fixed in the published package and verified through affected consumers.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions