diff --git a/internal/stacks/stackruntime/internal/stackeval/component.go b/internal/stacks/stackruntime/internal/stackeval/component.go index bfcd35a5f9..e5c2dd9336 100644 --- a/internal/stacks/stackruntime/internal/stackeval/component.go +++ b/internal/stacks/stackruntime/internal/stackeval/component.go @@ -110,7 +110,7 @@ func (c *Component) CheckForEachValue(ctx context.Context, phase EvalPhase) (cty switch { case cfg.ForEach != nil: - result, moreDiags := evaluateForEachExpr(ctx, cfg.ForEach, phase, c.Stack(ctx)) + result, moreDiags := evaluateForEachExpr(ctx, cfg.ForEach, phase, c.Stack(ctx), "component") diags = diags.Append(moreDiags) if diags.HasErrors() { return cty.DynamicVal, diags diff --git a/internal/stacks/stackruntime/internal/stackeval/component_test.go b/internal/stacks/stackruntime/internal/stackeval/component_test.go index 1ea75ffb7a..0f5cd2769b 100644 --- a/internal/stacks/stackruntime/internal/stackeval/component_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/component_test.go @@ -182,7 +182,7 @@ func TestComponentCheckInstances(t *testing.T) { gotVal, diags := component.CheckForEachValue(ctx, InspectPhase) assertMatchingDiag(t, diags, func(diag tfdiags.Diagnostic) bool { return (diag.Severity() == tfdiags.Error && - diag.Description().Detail == "The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this resource / data source / provider / component.") + diag.Description().Detail == "The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this component.") }) wantVal := cty.DynamicVal // placeholder for invalid result if !wantVal.RawEquals(gotVal) { diff --git a/internal/stacks/stackruntime/internal/stackeval/for_each.go b/internal/stacks/stackruntime/internal/stackeval/for_each.go index ec58f4fbcc..5c717e3eab 100644 --- a/internal/stacks/stackruntime/internal/stackeval/for_each.go +++ b/internal/stacks/stackruntime/internal/stackeval/for_each.go @@ -21,7 +21,7 @@ import ( // The caller might still need to do some further validation or post-processing // of the result for concerns that are specific to a particular phase or // evaluation context. -func evaluateForEachExpr(ctx context.Context, expr hcl.Expression, phase EvalPhase, scope ExpressionScope) (ExprResultValue, tfdiags.Diagnostics) { +func evaluateForEachExpr(ctx context.Context, expr hcl.Expression, phase EvalPhase, scope ExpressionScope, callerDiagName string) (ExprResultValue, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics result, moreDiags := EvalExprAndEvalContext( ctx, expr, phase, scope, @@ -37,7 +37,7 @@ func evaluateForEachExpr(ctx context.Context, expr hcl.Expression, phase EvalPha ty := result.Value.Type() const invalidForEachSummary = "Invalid for_each value" - const invalidForEachDetail = "The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this resource / data source / provider / component." + invalidForEachDetail := fmt.Sprintf("The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this %s.", callerDiagName) const sensitiveForEachDetail = "Sensitive values, or values derived from sensitive values, cannot be used as for_each arguments. If used, the sensitive value could be exposed as a resource instance key." switch { case result.Value.HasMark(marks.Sensitive): diff --git a/internal/stacks/stackruntime/internal/stackeval/for_each_test.go b/internal/stacks/stackruntime/internal/stackeval/for_each_test.go index 9aa0ebf03e..018d6849fc 100644 --- a/internal/stacks/stackruntime/internal/stackeval/for_each_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/for_each_test.go @@ -144,7 +144,7 @@ func TestEvaluateForEachExpr(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - gotResult, diags := evaluateForEachExpr(ctx, test.Expr, PlanPhase, scope) + gotResult, diags := evaluateForEachExpr(ctx, test.Expr, PlanPhase, scope, "test") got := gotResult.Value if test.WantErr != "" { diff --git a/internal/stacks/stackruntime/internal/stackeval/provider.go b/internal/stacks/stackruntime/internal/stackeval/provider.go index 14a223dde7..b3d83c244f 100644 --- a/internal/stacks/stackruntime/internal/stackeval/provider.go +++ b/internal/stacks/stackruntime/internal/stackeval/provider.go @@ -118,7 +118,7 @@ func (p *Provider) CheckForEachValue(ctx context.Context, phase EvalPhase) (cty. switch { case cfg.ForEach != nil: - result, moreDiags := evaluateForEachExpr(ctx, cfg.ForEach, phase, p.Stack(ctx)) + result, moreDiags := evaluateForEachExpr(ctx, cfg.ForEach, phase, p.Stack(ctx), "provider") diags = diags.Append(moreDiags) if diags.HasErrors() { return cty.DynamicVal, diags diff --git a/internal/stacks/stackruntime/internal/stackeval/provider_test.go b/internal/stacks/stackruntime/internal/stackeval/provider_test.go index 91e03e108f..bb77a5e0d7 100644 --- a/internal/stacks/stackruntime/internal/stackeval/provider_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/provider_test.go @@ -171,7 +171,7 @@ func TestProviderCheckInstances(t *testing.T) { gotVal, diags := provider.CheckForEachValue(ctx, InspectPhase) assertMatchingDiag(t, diags, func(diag tfdiags.Diagnostic) bool { return (diag.Severity() == tfdiags.Error && - diag.Description().Detail == "The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this resource / data source / provider / component.") + diag.Description().Detail == "The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this provider.") }) wantVal := cty.DynamicVal // placeholder for invalid result if !wantVal.RawEquals(gotVal) { diff --git a/internal/stacks/stackruntime/internal/stackeval/stack_call.go b/internal/stacks/stackruntime/internal/stackeval/stack_call.go index 45d78e7625..9a384b05b5 100644 --- a/internal/stacks/stackruntime/internal/stackeval/stack_call.go +++ b/internal/stacks/stackruntime/internal/stackeval/stack_call.go @@ -103,7 +103,7 @@ func (c *StackCall) CheckForEachValue(ctx context.Context, phase EvalPhase) (cty switch { case cfg.ForEach != nil: - result, moreDiags := evaluateForEachExpr(ctx, cfg.ForEach, phase, c.Caller(ctx)) + result, moreDiags := evaluateForEachExpr(ctx, cfg.ForEach, phase, c.Caller(ctx), "stack") diags = diags.Append(moreDiags) if diags.HasErrors() { return cty.DynamicVal, diags diff --git a/internal/stacks/stackruntime/internal/stackeval/stack_call_config.go b/internal/stacks/stackruntime/internal/stackeval/stack_call_config.go index 4d4326f676..15cb98f8fe 100644 --- a/internal/stacks/stackruntime/internal/stackeval/stack_call_config.go +++ b/internal/stacks/stackruntime/internal/stackeval/stack_call_config.go @@ -115,7 +115,7 @@ func (s *StackCallConfig) validateForEachValueInner(ctx context.Context) (cty.Va return cty.NilVal, diags } - result, moreDiags := evaluateForEachExpr(ctx, s.config.ForEach, ValidatePhase, s.CallerConfig(ctx)) + result, moreDiags := evaluateForEachExpr(ctx, s.config.ForEach, ValidatePhase, s.CallerConfig(ctx), "stack") diags = diags.Append(moreDiags) return result.Value, diags } diff --git a/internal/stacks/stackruntime/internal/stackeval/stack_call_test.go b/internal/stacks/stackruntime/internal/stackeval/stack_call_test.go index fb4bcbe107..63971e20cd 100644 --- a/internal/stacks/stackruntime/internal/stackeval/stack_call_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/stack_call_test.go @@ -177,7 +177,7 @@ func TestStackCallCheckInstances(t *testing.T) { gotVal, diags := call.CheckForEachValue(ctx, InspectPhase) assertMatchingDiag(t, diags, func(diag tfdiags.Diagnostic) bool { return (diag.Severity() == tfdiags.Error && - diag.Description().Detail == "The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this resource / data source / provider / component.") + diag.Description().Detail == "The for_each expression must produce either a map of any type or a set of strings. The keys of the map or the set elements will serve as unique identifiers for multiple instances of this stack.") }) wantVal := cty.DynamicVal // placeholder for invalid result if !wantVal.RawEquals(gotVal) {