Skip to content

Acknowledge pending workflow replay without empty-command completion errors #98

Description

@rmcdaniel

Observed defect

Published Python SDK 2.4.1 preserves a pending operation during replay, but its client submits commands: [] to /worker/workflow-tasks/{task_id}/complete. Server requires a nonempty command list and returns HTTP 422, The commands field is required.

This reproduces with published Server 2.3.12 and 2.5.6: start an echo activity followed by a durable timer, then signal while the timer is pending. Replay correctly retains the original timer, but its task acknowledgement is rejected. The workflow can later complete when the timer fires, hiding the failed acknowledgement in an otherwise successful final result.

PHP already sends empty-command replay through the established /fail acknowledgement with failure type WorkflowTaskWaitingForHistory. This is a waiting acknowledgement, not a workflow failure. Python should use the same protocol.

Required outcome

  • An empty-command replay acknowledges waiting with its original task ID, lease owner and attempt. It does not submit a rejected empty completion or invent a replacement operation.
  • Nonempty completion commands and their metadata retain their existing wire contract.
  • Message-stream progress cannot be silently discarded when choosing the waiting acknowledgement.
  • Add focused transport and worker regression coverage, then verify the published correction with repeated signals and cold replay while the original timer is pending. Require one timer and no empty-command HTTP 422s.

Found while rerunning the published-package continuity scenario after #96. The scalar replay fix remains correct. This is the additional transport acknowledgement gap its corrected pending path exposes.

Activity

  1. added
    authority:githubGitHub is the authoritative lifecycle record for this work
    kind:defectA public product behavior is incorrect
    priority:P1High-priority product or release risk
    completion:evidence-requiredClose only after all explicit acceptance and operational evidence is public
    intake:approvedCurrent issue title and body revision is approved for authority intake
    status:in-progressApproved work is actively being implemented or validated
    on Oct 7, 2026
  2. rmcdaniel commented on Oct 7, 2026

    @rmcdaniel
    MemberAuthor

    Delivered in PR #99, merged as 2fe5acc9f03664bd5fff5d298849931477247d81, and published as Python SDK 2.4.2. The immutable release tag points to that exact main commit.

    Exact PR and main CI pass 2,460 unit tests across Python 3.10/3.11/3.12 and 22 connected tests, plus lint, mypy, corpus and package checks. Publication succeeds. The live SDK reference documents the waiting acknowledgement and stream metadata guard. The merged branch is deleted.

    A normal PyPI install of 2.4.2 passes the published Server 2.3.12 to 2.5.6 recovery scenario with PHP 2.2.3 and Rust 3.2.0 on protocol 1.19. All nine original completed/waiting/queued workflows complete with identical 204800-byte external payloads and committed history prefixes. After repeated signals and SDK process SIGKILL while timers are still pending, waiting runs each have one scheduled/fired timer and total eighteen. Each run has one activity and workflow completion.

    The complete HTTP log has zero HTTP 422s and six successful waiting acknowledgements across 2,765 requests. Python logs have no workflow task completion error. Rust's temporary HTTP 502 exit during replacement is recovered by its normal supervisor. This verifies supervised recovery without promising uninterrupted worker processes. All disposable resources are removed. Nonempty completion parity and configured HTTP timeout tests remain passing. Stream metadata without commands is refused before a waiting request, so it cannot be silently discarded.

  3. added
    status:doneDerived from the authoritative closed issue state
    completion:evidence-verifiedAcceptance, fixed version, and required operational evidence are publicly verified
    and removed
    completion:evidence-requiredClose only after all explicit acceptance and operational evidence is public
    status:in-progressApproved work is actively being implemented or validated
    on Oct 7, 2026
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

    authority:githubGitHub is the authoritative lifecycle record for this workcompletion:evidence-verifiedAcceptance, fixed version, and required operational evidence are publicly verifiedintake:approvedCurrent issue title and body revision is approved for authority intakekind:defectA public product behavior is incorrectpriority:P1High-priority product or release riskstatus:doneDerived from the authoritative closed issue state

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions