hashicorp/terraform · error
at most 1 action can be invoked per operation
Error message
at most 1 action can be invoked per operation
What it means
Returned by the cloud backend plan path (cloud/backend_plan.go:186) when op.ActionTargets contains more than one entry. The -invoke-action CLI flag is currently limited to a single action address per operation; the backend re-checks this even though flag parsing already limits it, and emits a generalError('Invalid arguments', ...) wrapping this message.
Solutions
- Pass exactly one -invoke-action target per invocation.
- If you need multiple actions, run separate terraform plan/apply commands for each.
Example fix
# before terraform plan -invoke-action module.a -invoke-action module.b # after terraform plan -invoke-action module.a
Defensive patterns
Strategy: validation
Validate before calling
// Enforce single-action rule before building the operation.
if len(actionTargets) > 1 {
return errors.New("at most 1 action can be invoked per operation")
}
runOptions.InvokeActionAddrs = actionTargets[:1] Type guard
func singleAction(xs []string) bool { return len(xs) <= 1 } Prevention
- Pass -invoke-action at most once per command.
- Run separate plan/apply invocations for multiple actions.
- Validate the flag count in any wrapper before delegating to terraform.
When it happens
Trigger: Invoking terraform plan/apply with `-invoke-action` supplied more than once (or a future caller populating op.ActionTargets with >1 entry) so len(op.ActionTargets) > 1 at cloud/backend_plan.go:184-188.
Common situations: Passing `-invoke-action addr1 -invoke-action addr2`. A wrapper/tool constructing an Operation with multiple action targets.
Related errors
- action has config values with unsupported marks
- action has ephemeral config values, which are not supported…
- ErrInvalidRemotePlanFormat
- ErrInvalidRunID
- error in marshaling deferred action invocations
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/5d05cf02725e65aa.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cloud/backend_plan.go:186
if len(op.Targets) != 0 {
runOptions.TargetAddrs = make([]string, 0, len(op.Targets))
for _, addr := range op.Targets {
runOptions.TargetAddrs = append(runOptions.TargetAddrs, addr.String())
}
}
if len(op.ActionTargets) != 0 {
if len(op.ActionTargets) > 1 {
// For now, we only support a single action from the command line.
// We've future proofed the API and inputs so we can send multiple
// but versions of Terraform will enforce this both here, and
// on the other side.
//
// It shouldn't actually be possible to reach here anyway - we're
// validating at the point the flag is read that it only has a
// single entry. But, we'll check again to be safe.
return nil, b.generalError("Invalid arguments",
errors.New("at most 1 action can be invoked per operation"))
}
for _, target := range op.ActionTargets {
runOptions.InvokeActionAddrs = append(runOptions.InvokeActionAddrs, target.String())
}
}
if len(op.ForceReplace) != 0 {
runOptions.ReplaceAddrs = make([]string, 0, len(op.ForceReplace))
for _, addr := range op.ForceReplace {
runOptions.ReplaceAddrs = append(runOptions.ReplaceAddrs, addr.String())
}
}
if len(op.PolicyPaths) != 0 {
runOptions.PolicyPaths = append(runOptions.PolicyPaths, op.PolicyPaths...)
}View on GitHub (pinned to d32a084675)