Problem
mode: start's EIP association (src/aws.js ~L917-927) has three behaviors that hurt consumers whose EIP is load-bearing (e.g. a whitelisted egress IP the workload cannot run without):
AssociateAddressCommand is sent without AllowReassociation, so it fails with Resource.AlreadyAssociated whenever the EIP is still attached to a previous instance — including the action's own previous instance that is merely shutting-down after a mode: stop/terminate (EIP release only happens at terminated).
- The call is not wrapped in the action's own
withRetry, so a transient failure or the shutting-down race above gets no second chance, even though the condition self-heals within seconds.
- Failure is downgraded to
core.warning ("trying to proceed w/o EIP"). For an EIP-is-egress consumer the instance then boots with no outbound connectivity, the runner never registers, and the start step dies minutes later on the generic registration timeout — nothing in the failure names the EIP.
Consumer-side evidence
namecheap/terraform-provider-namecheap carries a workaround step ("Wait for the sandbox EIP to be free", .github/workflows/ci.yml, added in namecheap/terraform-provider-namecheap#327 and hardened in #337/#338/#339) that polls DescribeAddresses before mode: start purely to avoid this race. Every consumer with a dedicated EIP has to re-invent that shim.
Proposal
- Retry the association (reusing
withRetry) — the shutting-down race self-heals, so 3 attempts with backoff removes most failures.
- Either always set
AllowReassociation: true when the current association is a shutting-down/stopped instance managed by this action, or expose it as an input.
- Add an input (e.g.
eip-required: true) that promotes association failure to a hard, immediate error naming the EIP — failing in 2 seconds with a clear message instead of ~5.5 minutes with a generic one.
When this lands, the consumer-side shim above can be deleted.
Problem
mode: start's EIP association (src/aws.js~L917-927) has three behaviors that hurt consumers whose EIP is load-bearing (e.g. a whitelisted egress IP the workload cannot run without):AssociateAddressCommandis sent withoutAllowReassociation, so it fails withResource.AlreadyAssociatedwhenever the EIP is still attached to a previous instance — including the action's own previous instance that is merelyshutting-downafter amode: stop/terminate (EIP release only happens atterminated).withRetry, so a transient failure or the shutting-down race above gets no second chance, even though the condition self-heals within seconds.core.warning("trying to proceed w/o EIP"). For an EIP-is-egress consumer the instance then boots with no outbound connectivity, the runner never registers, and the start step dies minutes later on the generic registration timeout — nothing in the failure names the EIP.Consumer-side evidence
namecheap/terraform-provider-namecheapcarries a workaround step ("Wait for the sandbox EIP to be free",.github/workflows/ci.yml, added in namecheap/terraform-provider-namecheap#327 and hardened in #337/#338/#339) that pollsDescribeAddressesbeforemode: startpurely to avoid this race. Every consumer with a dedicated EIP has to re-invent that shim.Proposal
withRetry) — the shutting-down race self-heals, so 3 attempts with backoff removes most failures.AllowReassociation: truewhen the current association is ashutting-down/stoppedinstance managed by this action, or expose it as an input.eip-required: true) that promotes association failure to a hard, immediate error naming the EIP — failing in 2 seconds with a clear message instead of ~5.5 minutes with a generic one.When this lands, the consumer-side shim above can be deleted.