hashicorp/terraform · error
action has ephemeral config values, which are not supported…
Error message
action %s has ephemeral config values, which are not supported in action invocations
What it means
Action invocation config contains ephemeral marks. Ephemeral values are intentionally non-serializable, so the plan JSON renderer refuses to embed them in an action invocation's config.
Solutions
- Remove ephemeral inputs from the action invocation config; pass non-ephemeral values instead.
- Wait for / upgrade to a Terraform version that supports ephemeral config in action invocations.
- If marks are unexpected, trace where the ephemeral mark was applied — it may indicate an upstream bug.
Defensive patterns
Strategy: validation
Validate before calling
// Check an action config value for ephemeral marks before marshaling.
func hasEphemeral(v cty.Value) bool {
_, pms := v.UnmarkDeepWithPaths()
_, _ = marks.PathsWithMark(pms, marks.Sensitive)
ephemeral, _ := marks.PathsWithMark(pms, marks.Ephemeral) // simplified
return len(ephemeral) > 0
} Prevention
- Avoid routing ephemeral values (write-only secrets, ephemeral resources) into action invocation config.
- Track ephemeral propagation in expressions during config authoring.
When it happens
Trigger: An action block references an ephemeral variable/resource output or a value derived from one; ephemeral marks propagated through expressions into the action config.
Common situations: Using ephemeral values (write-only secrets, ephemeral resources) inside an action invocation, which the current plan-renderer does not support.
Related errors
- action has config values with unsupported marks
- error in marshaling deferred action invocations
- error marshaling action invocations
- failed to decode action
- no schema found for (in provider )
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/8999da81782ae895.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/jsonplan/action_invocations.go:162
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)
unknown, err = ctyjson.Marshal(unknownValue, unknownValue.Type())
if err != nil {
return ai, err
}
configValue := omitUnknowns(unmarkedValue)
config, err = ctyjson.Marshal(configValue, configValue.Type())
if err != nil {
return ai, err
}
sensitivePaths = append(sensitivePaths, schema.ConfigSchema.SensitivePaths(unmarkedValue, nil)...)View on GitHub (pinned to d32a084675)