VariableBlock panics when planning object-typed variables
- Dominant language
- Go
- Stars
- 3
- Forks
- 13
- PR merge metrics
- No merged PRs in 30d
Description
### Summary
Planning a variable declared with an `object(...)` type panics in `VariableBlock.ExecuteBeforePlan` instead of accepting or converting the value.
This reproduces on the current `main` commit, `6e9a3fc2760e6f8440e4dfe8d0b1360886588bdd`.
### Reproduction
Add this test to `variable_test.go`:
```go
func (s *variableSuite) TestExecuteBeforePlan_ObjectTypedDefault() {
s.dummyFsWithFiles(map[string]string{
"test.hcl": `
variable "provider" {
type = object({
type = string
endpoint = string
})
default = {
type = "openai"
endpoint = "https://example.test/v1"
}
}
`,
})
config, err := BuildDummyConfig("/", "", nil, nil)
require.NoError(s.T(), err)
variable := Blocks[*VariableBlock](config)[0]
s.Equal(cty.ObjectVal(map[string]cty.Value{
"type": cty.StringVal("openai"),
"endpoint": cty.StringVal("https://example.test/v1"),
}), *variable.variableValue)
}
```
Run:
```console
go test ./... -run 'TestVariableSuite/TestExecuteBeforePlan_ObjectTypedDefault' -count=1
```
The test was run as written and fails before reaching the assertions:
```text
--- FAIL: TestVariableSuite (0.00s)
--- FAIL: TestVariableSuite/TestExecuteBeforePlan_ObjectTypedDefault (0.00s)
alg.go:337: test panicked: runtime error: comparing uncomparable type cty.typeObject
...
github.com/Azure/golden.(*VariableBlock).ExecuteBeforePlan(...)
variable.go:100
```
Environment used for the reproduction:
```text
go version go1.26.5 windows/amd64
```
### Expected behavior
`BuildDummyConfig` should succeed and `var.provider` should contain the declared object value. If the source value requires a compatible conversion, Golden should pass it through `convert.Convert`; an incompatible value should return the existing diagnostic rather than panic.
### Root cause
[`VariableBlock.ExecuteBeforePlan`](https://github.com/Azure/golden/blob/6e9a3fc2760e6f8440e4dfe8d0b1360886588bdd/variable.go#L100) compares two `cty.Type` values with Go's `!=` operator:
```go
if v.variableType != nil && value.Type() != *v.variableType {
```
A `cty.Type` wraps its concrete type implementation. `cty.typeObject` contains a map of attribute types, so comparing it through `==` or `!=` causes Go to panic because maps are not comparable. The panic occurs even when the declared and actual object types are structurally equal.
### Suggested fix
Use cty's structural type comparison API:
```go
if v.variableType != nil && !value.Type().Equals(*v.variableType) {
```
The regression test above should remain to cover the equal object-type path. A second case with a convertible object value would also protect the existing `convert.Convert` behavior.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with VariableBlock.ExecuteBeforePlan in variable.go and the regression test in variable_test.go. Run the supplied go test command, then verify that the object-typed default reaches the expected cty value and that incompatible values still produce the existing diagnostic instead of panicking.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend, testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100