coder / coder/preview

Unknown parameter default coerced to null skips the 'value is unknown' diagnostic

Open
#225 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
9
Forks
5
Avg merge
3d 20h
Merged PRs (30d)
2

Description

## Summary

A parameter whose `default` is an unknown value can surface either as an error diagnostic or as a silent null, depending on how the unknown arrives. Both cases are "the value could not be resolved", but only one of them tells the user.

## Repro

`testdata/resourceclosure2` on `main` (from #224):

```hcl
resource "docker_image" "base" { name = "large" }

data "coder_parameter" "computed" {
name = "computed"
type = "string"
default = docker_image.base.image_id # computed attribute, unknown at plan time
}
```

Result on `main`:

```
value=cty.NullVal(cty.String) valid=false known=false null=true default=cty.DynamicVal diags=0
```

`DefaultValue` is `cty.DynamicVal`, `Value` ends up as a typed null, and the parameter carries **no diagnostics**.

Compare a default that is unknown because a reference has no value (for example `default = local.x` where `local.x` reads a block that does not exist). There the value stays an unknown and `ParameterUsageDiagnostics` emits:

```
Parameter value is unknown, it likely includes a reference without a value
```

## Where it diverges

`extract/parameter.go`, `ParameterUsageDiagnostics`:

```go
if p.Value.Value.IsNull() {
// Allow null values
} else if !p.Value.Valid() {
...
} else if !p.Value.IsKnown() {
... "Parameter value is unknown" ...
}
```

The null branch is checked first, so an unknown default that is coerced to a typed null on the way to `Value` skips both the "not valid" and "unknown" branches, even though `Valid()` and `IsKnown()` are both false on it.

## Expected

Either both shapes report the same "unknown / unresolved" diagnostic, or neither does. A user writing `default = ` gets a required-but-empty parameter in the form with no explanation today.

## Notes

- Found while writing #224; the `computed` vector there pins the current behavior with `ap().unknown()` and no diagnostic assertion, so it will not block a fix.
- Not related to the resource-closure work in #221; reproduces on `main` with no pruning.

Filed by Emyrk with Coder Agents assistance.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.