Fix error message when default value of variable is of wrong type (#2444)

Signed-off-by: yottta <andrei.ciobanu@opentofu.org>
This commit is contained in:
Andrei Ciobanu 2025-01-29 10:50:45 +02:00 committed by GitHub
parent 77c19fab1e
commit ab9a7f4d72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 2 deletions

View File

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/hcl/v2/ext/typeexpr"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/opentofu/opentofu/internal/tfdiags"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/convert"
@ -157,7 +158,7 @@ func decodeVariableBlock(block *hcl.Block, override bool) (*Variable, hcl.Diagno
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid default value for variable",
Detail: fmt.Sprintf("This default value is not compatible with the variable's type constraint: %s.", err),
Detail: fmt.Sprintf("This default value is not compatible with the variable's type constraint: %s.", tfdiags.FormatError(err)),
Subject: attr.Expr.Range().Ptr(),
})
val = cty.DynamicVal

View File

@ -92,47 +92,61 @@ func TestParserLoadConfigFileFailure(t *testing.T) {
// This test uses a subset of the same fixture files as
// TestParserLoadConfigFileFailure, but additionally verifies that each
// file produces the expected diagnostic summary.
// file produces the expected diagnostic summary and detail.
func TestParserLoadConfigFileFailureMessages(t *testing.T) {
tests := []struct {
Filename string
WantSeverity hcl.DiagnosticSeverity
WantDiag string
WantDetail string
}{
{
"invalid-files/data-resource-lifecycle.tf",
hcl.DiagError,
"Invalid data resource lifecycle argument",
`The lifecycle argument "ignore_changes" is defined only for managed resources ("resource" blocks), and is not valid for data resources.`,
},
{
"invalid-files/variable-type-unknown.tf",
hcl.DiagError,
"Invalid type specification",
`The keyword "notatype" is not a valid type specification.`,
},
{
"invalid-files/unexpected-attr.tf",
hcl.DiagError,
"Unsupported argument",
`An argument named "foo" is not expected here.`,
},
{
"invalid-files/unexpected-block.tf",
hcl.DiagError,
"Unsupported block type",
`Blocks of type "varyable" are not expected here. Did you mean "variable"?`,
},
{
"invalid-files/resource-count-and-for_each.tf",
hcl.DiagError,
`Invalid combination of "count" and "for_each"`,
`The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.`,
},
{
"invalid-files/data-count-and-for_each.tf",
hcl.DiagError,
`Invalid combination of "count" and "for_each"`,
`The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.`,
},
{
"invalid-files/resource-lifecycle-badbool.tf",
hcl.DiagError,
"Unsuitable value type",
`Unsuitable value: a bool is required`,
},
{
"invalid-files/variable-complex-bad-default-inner-obj.tf",
hcl.DiagError,
"Invalid default value for variable",
`This default value is not compatible with the variable's type constraint: ["mykey"].field: a bool is required.`,
},
}
@ -161,6 +175,9 @@ func TestParserLoadConfigFileFailureMessages(t *testing.T) {
if diags[0].Summary != test.WantDiag {
t.Errorf("Wrong diagnostic summary\ngot: %s\nwant: %s", diags[0].Summary, test.WantDiag)
}
if diags[0].Detail != test.WantDetail {
t.Errorf("Wrong diagnostic detail\ngot: %s\nwant: %s", diags[0].Detail, test.WantDetail)
}
})
}
}

View File

@ -0,0 +1,15 @@
// https://github.com/opentofu/opentofu/issues/2394
// This validates the returned error message when the default value
// inner field type does not match the definition of the variable
variable "bad_type_for_inner_field" {
type = map(object({
field = bool
}))
default = {
"mykey" = {
field = "not a bool"
dont = "mind me"
}
}
}