hashicorp/terraform · error

failed to decode action

Error message

failed to decode action %s: %w

What it means

Wrapper error from MarshalActionInvocations: it iterates action invocation instances and re-wraps any per-action failure returned by MarshalActionInvocation. The message identifies which action (by Addr) failed and chains the underlying error with %w.

Solutions

  1. Read the chained %w error first — it names the actual cause (603/604/605/606/607).
  2. Re-init the provider (`terraform init -upgrade`) so the action type schema is present.
  3. Upgrade Terraform to a version that supports the action trigger type or marks involved.
  4. If the plan was produced by a newer Terraform, regenerate it with the current version.
Defensive patterns

Strategy: try-catch

Try / catch

out, err := MarshalActionInvocations(actions, schemas)
if err != nil {
    // err already chains the per-action cause via %%w; unwrap to branch on it
    return fmt.Errorf("cannot render action invocations: %%w", err)
}

Prevention

When it happens

Trigger: Any failure inside MarshalActionInvocation for a single action propagates here: missing schema (603), decode failure (604), unsupported trigger type (605), ephemeral marks (606), or unsupported marks (607).

Common situations: Plan contains action invocations whose provider schema is stale, whose action trigger type is unrecognized by this Terraform version, or whose config carries marks this version cannot serialize.

Understand the failure class

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/38f8f098a5fab6f5. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/jsonplan/action_invocations.go:108

		}

		if latA.ActionsListIndex < latB.ActionsListIndex {
			return -1

		} else if latA.ActionsListIndex > latB.ActionsListIndex {
			return 1
		}
	}

	return 0
}

func MarshalActionInvocations(actions []*plans.ActionInvocationInstanceSrc, schemas *terraform.Schemas) ([]ActionInvocation, error) {
	ret := make([]ActionInvocation, 0, len(actions))
	for _, action := range actions {
		ai, err := MarshalActionInvocation(action, schemas)
		if err != nil {
			return ret, fmt.Errorf("failed to decode action %s: %w", action.Addr, err)
		}
		ret = append(ret, ai)
	}
	return ret, nil
}

func MarshalActionInvocation(action *plans.ActionInvocationInstanceSrc, schemas *terraform.Schemas) (ActionInvocation, error) {
	ai := ActionInvocation{
		Address:      action.Addr.String(),
		Type:         action.Addr.Action.Action.Type,
		Name:         action.Addr.Action.Action.Name,
		ProviderName: action.ProviderAddr.Provider.String(),
	}
	schema := schemas.ActionTypeConfig(
		action.ProviderAddr.Provider,
		action.Addr.Action.Action.Type,
	)
	if schema.ConfigSchema == nil {

View on GitHub (pinned to d32a084675)