DEV Community

Cover image for Catch and Recover from a Failed AWS Step Functions Task
miruky
miruky

Posted on

Catch and Recover from a Failed AWS Step Functions Task

Introduction

Hi, I'm miruky.

An AWS Step Functions Task failure ends a workflow unless a retry succeeds or a catcher handles the reported error. A useful catcher should recognize one expected failure without converting unrelated faults into success.

The design has three fixed parts: an AWS SDK GetParameter Task, an ErrorEquals entry for Ssm.ParameterNotFoundException, and a Recovered Pass state with a small result object.

I use an Express workflow with execution logging set to OFF. The design excludes both Standard workflow history and a CloudWatch Logs copy; Section 4 inspects only the immediate synchronous response.

No Lambda function, Parameter Store parameter, or CloudWatch Logs log group is created. A clean run of the finished path performs one short Express execution and one GetParameter request. Check the current Step Functions and Parameter Store pricing pages before adapting the pattern to a recurring workload.

1. Establish the missing-parameter condition

The validation starts from an English AWS Console in N. Virginia.

The English AWS Console shows the Step Functions service in N. Virginia.

The header shows United States (N. Virginia) while the Step Functions Console is in English. This fixes us-east-1 as the Regional context for the state machine and its Parameter Store call.

Next, open Parameter Store without creating a parameter.

Parameter Store shows its first-use page because the Region contains no parameters.

The page shows Start to use Parameter Store and Create parameter, with no parameter list in this Region. The generated name miruky-awyoqxtnwnrjhexm is therefore absent, and the exercise never creates it.

If your account already has parameters, search for the full generated name and confirm that no exact row exists. If it does exist, stop and generate a new name; do not inspect, modify, or delete a resource that belongs to another workload.

2. Create the execution role

The workflow needs permission to read only the intended parameter path. It does not need permission to create, change, list, or delete parameters.

The trust policy needs your AWS account ID in two places. Replace both YOUR_ACCOUNT_ID placeholders in the Console, and keep the real value out of screenshots, notes, and published Markdown.

Use this trust policy for the role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "states.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:states:us-east-1:YOUR_ACCOUNT_ID:stateMachine:*"
        },
        "StringEquals": {
          "aws:SourceAccount": "YOUR_ACCOUNT_ID"
        }
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The service principal allows Step Functions to assume the role. The two conditions limit that trust to state machines from the current account in N. Virginia, following the confused-deputy guidance in the Step Functions documentation.

Add an inline policy named miruky-fswatmkcbokhffcr:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ssm:GetParameter",
      "Resource": "arn:aws:ssm:us-east-1:*:parameter/miruky-awyoqxtnwnrjhexm",
      "Condition": {
        "StringEquals": {
          "aws:ResourceAccount": "${aws:PrincipalAccount}"
        }
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The policy summary makes the permission boundary visible without publishing the account segment of the ARN.

The inline policy selects GetParameter as the only Systems Manager action.

GetParameter is selected as the only action; the adjacent read operations remain unchecked. No write or list permission broadens the exercise.

The resource and condition fields provide a separate scope check before the policy is saved.

The inline policy scopes GetParameter to the generated path and the principal account.

The Resources field contains one N. Virginia parameter ARN ending in miruky-awyoqxtnwnrjhexm. The request condition shows aws:ResourceAccount (StringEquals) ${aws:PrincipalAccount}, so the wildcard account segment cannot authorize a parameter from another account.

The completed role provides a second checkpoint before Step Functions can assume it.

The role details show the single generated inline GetParameter policy.

The role has one permissions policy, the inline policy miruky-fswatmkcbokhffcr. No unrelated managed policy is attached, while the trust relationship remains the Step Functions policy defined above.

3. Define the specific catcher

The generated state-machine name must also be unused before creation.

The Step Functions list has no exact match for the generated state-machine name.

The exact search for miruky-pxnzifxuhsojmzmb returns No state machines. This avoids modifying or replacing an existing workflow.

Use the following Amazon States Language definition:

{
  "Comment": "Catch an expected missing-parameter error.",
  "StartAt": "ReadMissingParameter",
  "States": {
    "ReadMissingParameter": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:ssm:getParameter",
      "Parameters": {
        "Name": "miruky-awyoqxtnwnrjhexm"
      },
      "Catch": [
        {
          "ErrorEquals": [
            "Ssm.ParameterNotFoundException"
          ],
          "Next": "Recovered"
        }
      ],
      "Next": "UnexpectedSuccess"
    },
    "Recovered": {
      "Type": "Pass",
      "Result": {
        "status": "recovered",
        "reason": "parameter-not-found"
      },
      "End": true
    },
    "UnexpectedSuccess": {
      "Type": "Fail",
      "Error": "UnexpectedParameterPresent",
      "Cause": "The validation parameter existed."
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The editor exposes both the intended recovery route and the guard against an unexpected success.

The state-machine editor shows the SDK Task, specific Catch rule, and recovery state.

ReadMissingParameter catches only Ssm.ParameterNotFoundException and routes that value to Recovered. A successful read goes to UnexpectedSuccess, which fails the workflow because the precondition would no longer hold.

The visual workflow exposes the two terminal paths before creation.

The workflow graph separates the caught recovery branch from the unexpected-success failure branch.

The Catch #1 branch ends at Recovered, while the normal service-call edge ends at UnexpectedSuccess. That separation prevents the exercise from reporting success if the supposedly absent parameter is present.

AWS SDK integrations construct catchable errors differently from the source API name. The Step Functions service prefix is PascalCase, and the exception name needs the Exception suffix. That is why the SSM API error ParameterNotFound becomes Ssm.ParameterNotFoundException in ErrorEquals.

The state-machine configuration controls both execution behavior and retained data. Select the existing role miruky-ijbldxcdcaabrrxe rather than asking Workflow Studio to create another role.

The state-machine settings select the Express workflow type.

The Express card is selected, which enables a synchronous Console invocation and does not retain Step Functions execution history. The execution role still supplies the narrowly scoped GetParameter permission at runtime.

Set the execution log level to OFF for this one-time validation.

The logging settings show the OFF log level for the Express workflow.

OFF prevents Step Functions from delivering execution events to CloudWatch Logs. Because no log destination is configured, this run does not create an execution-history log group.

Open Additional configuration and leave X-Ray tracing disabled.

Additional configuration shows Enable X-Ray tracing unchecked.

The Enable X-Ray tracing checkbox is unchecked, as are the unrelated versioning and customer-managed-key options. The validation therefore adds neither X-Ray traces nor a new KMS dependency.

4. Run synchronously and verify recovery

A synchronous invocation returns the final output directly to the Console.

The start-execution dialog selects a synchronous run with generated input metadata.

The dialog uses Synchronous, a generated execution name, and {} as the input. The input contains no user, account, or application data, and the Open in a new browser tab checkbox remains unchecked.

After the short request finishes, the returned result proves which terminal branch ran.

The synchronous Express result succeeds with the deterministic recovery object.

The dialog reports Express execution completed successfully. and returns an output containing only recovered and parameter-not-found. Recovered is the only state that can produce that object, while an existing parameter would have reached UnexpectedSuccess and returned a failed result.

The final Console view confirms that logging-off Express runs do not become stored execution history.

The Executions tab shows logging disabled and no retained execution rows.

The Executions tab contains no execution rows and displays Logging is disabled. This matches the documented Express behavior: Step Functions does not capture Express execution history, and the Console can reconstruct it only from CloudWatch Logs when logging is enabled.

Wrap-up

The service call failed for the intended reason, the catcher matched the exact Step Functions error name, and the workflow returned a small success object through Recovered. A permissions error, malformed request, timeout, or another unexpected task failure would remain unhandled and visible instead of being hidden behind States.ALL.

Synchronous Express also kept this one-time validation from leaving a Standard execution record. That choice is useful for this controlled demonstration; production systems may need CloudWatch Logs or a Standard workflow when durable execution history is part of the operational requirement.

Thanks for reading this far.

See you in the next one.

Disclosure: This article was written with AI assistance and independently verified against the linked primary sources and observed results.

References

Top comments (0)