Skip to content

Non-retryable AWS errors (AccessDenied) are retried in an infinite loop instead of failing fast #4

Description

@cnuss

Summary

When an AWS API call returns a non-retryable client error — e.g. AccessDenied (HTTP 403) from a missing IAM permission, or ValidationError (HTTP 400) — rowdy keeps retrying it in a loop rather than failing the step. The deploy never exits; it just spins until the GitHub Actions job is cancelled or times out (observed 7+ minutes with no progress).

Repro

Run a Lambda deploy where the assuming role is missing a permission the deploy needs, e.g. lambda:CreateFunction:

- uses: scaffoldly/rowdy@github
  with:
    cloud: aws
    compute: lambda
    image: ghcr.io/owasp-ctf/score:latest

Observed

The [LambdaClient] [CreateFunctionCommand] (and earlier [IAMClient] calls) return AccessDenied, and rowdy retries the same call indefinitely. The step makes no forward progress and has to be cancelled manually.

AccessDenied / ValidationError are $fault: 'client' and $retryable: undefined in the SDK response — they will never succeed on retry, so retrying is pointless.

Expected

Fail fast on non-retryable client errors (4xx that aren't throttling/5xx). Surface the underlying AccessDenied message and exit non-zero so the operator sees exactly which action/resource is missing. Reserve retries for genuinely transient errors (throttling, 5xx, network).

Related

Surfaced while working around #3 — the infinite retry made the missing-permission failures much harder to diagnose, since the real error scrolls by repeatedly with no terminal failure.

Environment

  • scaffoldly/rowdy@github, ubuntu-latest, Node 24
  • AWS us-east-1, compute: lambda

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions