hashicorp/terraform · error

unsupported action trigger type: %T

Error message

unsupported action trigger type: %T

What it means

MarshalActionInvocation switches on action.ActionTrigger and only handles *plans.ResourceActionTrigger and *plans.InvokeActionTrigger (the only two implementations of the ActionTrigger interface). The default branch fires for any other concrete type, including a nil interface. This is an internal invariant violation rather than a configuration error.

Source

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

		return ai, fmt.Errorf("failed to decode action %s: %w", action.Addr, err)
	}

	switch at := action.ActionTrigger.(type) {
	case *plans.ResourceActionTrigger:
		ai.LifecycleActionTrigger = &LifecycleActionTrigger{
			TriggeringResourceAddress: at.TriggeringResourceAddr.String(),
			ActionTriggerEvent:        at.TriggerEvent().String(),
			ActionTriggerBlockIndex:   at.ActionTriggerBlockIndex,
			ActionsListIndex:          at.ActionsListIndex,
			OnFailure:                 at.ActionOnFailure.String(),
		}
	case *plans.InvokeActionTrigger:
		ai.InvokeActionTrigger = &InvokeActionTrigger{}
		if at.CallingResourceAddr != nil {
			ai.InvokeActionTrigger.CallingResourceAddress = at.CallingResourceAddr.String()
		}
	default:
		return ai, fmt.Errorf("unsupported action trigger type: %T", at)
	}

	var config []byte
	var sensitive []byte
	var unknown []byte

	if actionDec.ConfigValue != cty.NilVal {
		unmarkedValue, pvms := actionDec.ConfigValue.UnmarkDeepWithPaths()
		sensitivePaths, otherMarks := marks.PathsWithMark(pvms, marks.Sensitive)
		ephemeralPaths, otherMarks := marks.PathsWithMark(otherMarks, marks.Ephemeral)
		if len(ephemeralPaths) > 0 {
			return ai, fmt.Errorf("action %s has ephemeral config values, which are not supported in action invocations", action.Addr)
		}
		if len(otherMarks) > 0 {
			return ai, fmt.Errorf("action %s has config values with unsupported marks: %v", action.Addr, otherMarks)
		}

		unknownValue := unknownAsBool(unmarkedValue)

View on GitHub (pinned to c9def3e214)

Solutions

  1. Report this as a Terraform-internal bug; it is not reachable through normal HCL configuration.
  2. If you maintain a fork that added a trigger type, add a matching case in action_invocations.go:135.
  3. Ensure all Terraform binaries involved come from one consistent build (no partial rebuild of internal packages).
Defensive patterns

Strategy: type-guard

Type guard

func supportedActionTrigger(t plans.ActionTrigger) bool {
    switch t.(type) {
    case *plans.ResourceActionTrigger, *plans.InvokeActionTrigger:
        return true
    }
    return false
}

// use before marshaling
for _, a := range actions {
    if !supportedActionTrigger(a.ActionTrigger) {
        return fmt.Errorf("unsupported action trigger %T for %s", a.ActionTrigger, a.Addr)
    }
}

Prevention

When it happens

Trigger: Triggered when ActionTrigger holds a value whose dynamic type is neither *ResourceActionTrigger nor *InvokeActionTrigger, or is nil. Only reachable if a third ActionTrigger implementation is introduced into the plans package without a matching case here, or via a custom/forked build.

Common situations: Development of a new action trigger feature in a fork where the renderer was not updated; mismatched internal packages where plans and jsonplan come from different builds; a nil trigger field due to an upstream construction bug.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/5f0919250c9cd909. Report an issue: GitHub.