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
Summary
When an AWS API call returns a non-retryable client error — e.g.
AccessDenied(HTTP 403) from a missing IAM permission, orValidationError(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:Observed
The
[LambdaClient] [CreateFunctionCommand](and earlier[IAMClient]calls) returnAccessDenied, and rowdy retries the same call indefinitely. The step makes no forward progress and has to be cancelled manually.AccessDenied/ValidationErrorare$fault: 'client'and$retryable: undefinedin 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 underlyingAccessDeniedmessage 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 24us-east-1,compute: lambda