Skip to content

[Bug]: Emulator retries invalid invocation outputs that the service fails immediately #670

Description

@yaythomas

Expected Behavior

The emulator should mirror the service's handling of invalid invocation outputs. Verified service behavior:

Most invalid outputs fail the execution immediately, with no retry. This applies to:

  • Status=FAILED with a Result present
  • Status=SUCCEEDED with an Error present
  • a missing or unrecognized Status
  • an unparseable/malformed invocation output payload

In each case the service fails the execution with an error object of the form:

{
  "ErrorType": "InvalidParameterValueException",
  "ErrorMessage": "<the specific validation message>"
}

There is exactly one retried case: Status=PENDING when the execution has no pending operations. The service treats this as a transient runtime-level error (it can arise from SDK race conditions that resolve on replay) and retries the invocation, up to 3 consecutive attempts, before failing the execution with the same InvalidParameterValueException-shaped error.

Actual Behavior

In aws_durable_execution_sdk_python_testing.executor.Executor._finish_invocation(), all validation failures from _validate_invocation_response_and_store() are routed through the same retry path:

except (InvalidParameterValueException, IllegalStateException) as e:
    ...
    self._set_invocation_gate(execution_arn, InvocationState.PRE_INVOKE)
    self._retry_invocation(execution, error_obj)
    return

_retry_invocation re-invokes the handler up to MAX_CONSECUTIVE_FAILED_ATTEMPTS = 5 times with a flat RETRY_BACKOFF_SECONDS = 5 backoff before failing.

Consequences:

  • A deterministically invalid output (e.g. SUCCEEDED with an Error) is re-invoked 5 times before failing, where the service fails on the first response. For a deterministic handler this adds ~25 seconds and 4 pointless invocations, and every re-invocation replays the handler.
  • The one case the service does retry (PENDING with no pending operations) gets 5 attempts instead of 3.
  • The terminal error surfaced to the customer is ErrorObject.from_exception(e) rather than the service's {ErrorType: "InvalidParameterValueException", ErrorMessage: ...} shape.

Proposed Fix

In _finish_invocation, distinguish the two classes:

  • Fail-fast validation errors (FAILED+Result, SUCCEEDED+Error, missing/unknown status, malformed output): fail the execution immediately with an InvalidParameterValueException-typed error object carrying the validation message.
  • PENDING with no pending operations: keep the retry path, with a consecutive-attempt cap of 3.

Regression tests:

  • each fail-fast case produces a FAILED execution after a single invocation, with the InvalidParameterValueException error shape;
  • PENDING with no pending operations retries and fails after 3 consecutive attempts;
  • a transient case (invalid output once, then a valid PENDING/SUCCEEDED) recovers without failing the execution.

Related

SDK Version

aws-durable-execution-sdk-python-testing current main as of 2026-08-21.

Python Version

3.13

Is this a regression?

No known working version.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugparityProvides parity with other language implementations of the SDKpkg:testingPackage: aws-durable-execution-sdk-python-testing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions