Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/v1.15/BUG FIXES-20251028-104850.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: BUG FIXES
body: Improve wording of for_each key dependency error when using a set
time: 2025-10-28T10:48:50.112437+00:00
custom:
Issue: ""
2 changes: 1 addition & 1 deletion internal/terraform/eval_for_each.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func (ev *forEachEvaluator) ensureKnownForResource(forEachVal cty.Value) tfdiags
var diags tfdiags.Diagnostics
ty := forEachVal.Type()
const errInvalidUnknownDetailMap = "The \"for_each\" map includes keys derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will identify the instances of this resource.\n\nWhen working with unknown values in for_each, it's better to define the map keys statically in your configuration and place apply-time results only in the map values.\n\nAlternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge."
const errInvalidUnknownDetailSet = "The \"for_each\" set includes values derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will identify the instances of this resource.\n\nWhen working with unknown values in for_each, it's better to use a map value where the keys are defined statically in your configuration and where only the values contain apply-time results.\n\nAlternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge."
const errInvalidUnknownDetailSet = "The \"for_each\" set includes elements derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will identify the instances of this resource.\n\nWhen working with unknown values in for_each, it's better to use a map value where the map keys are defined statically in your configuration and only the map values contain apply-time results.\n\nAlternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge."

if !forEachVal.IsKnown() {
var detailMsg string
Expand Down
6 changes: 3 additions & 3 deletions internal/terraform/eval_for_each_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func TestEvaluateForEachExpression_errors(t *testing.T) {
"unknown string set": {
hcltest.MockExprLiteral(cty.UnknownVal(cty.Set(cty.String))),
"Invalid for_each argument",
"set includes values derived from resource attributes that cannot be determined until apply",
"set includes elements derived from resource attributes that cannot be determined until apply",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "elements" of a set are the conceptual placeholders for the value (in the implementation, Element() actually returns the key-value pair), but it is still a "value" which is derived from an expression. I see how the wording above is a bit clumsy with the repeated use of "value", but I don't think this is more clear. That could be because I'm used to communicating in Terraform's language, so I wonder if anyone else find this problematic enough to change.

true, false, false,
},
"unknown map": {
Expand Down Expand Up @@ -174,13 +174,13 @@ func TestEvaluateForEachExpression_errors(t *testing.T) {
"set containing unknown value": {
hcltest.MockExprLiteral(cty.SetVal([]cty.Value{cty.UnknownVal(cty.String)})),
"Invalid for_each argument",
"set includes values derived from resource attributes that cannot be determined until apply",
"set includes elements derived from resource attributes that cannot be determined until apply",
true, false, false,
},
"set containing dynamic unknown value": {
hcltest.MockExprLiteral(cty.SetVal([]cty.Value{cty.UnknownVal(cty.DynamicPseudoType)})),
"Invalid for_each argument",
"set includes values derived from resource attributes that cannot be determined until apply",
"set includes elements derived from resource attributes that cannot be determined until apply",
true, false, false,
},
"set containing sensitive values": {
Expand Down