terraform-plugin-framework
terraform-plugin-framework copied to clipboard
`Plan` and `State` `SetAttribute` methods do not support setting an untyped nil value
Module version
% go list -m github.com/hashicorp/terraform-plugin-framework/...
github.com/hashicorp/terraform-plugin-framework v0.1.0
Actual Behavior
The Plan.SetAttribute and State.SetAttribute methods do not currently support setting a Null value via state.SetAttribute(ctx, path, nil). I get the error
error setting value at AttributeName("identifier"): error creating new state value: don't know how to construct attr.Type from <nil> (invalid)
Expected Behavior
To be able to set a Null value (of the type specified at path) in State (and Plan, although I am not currently concerned with that case).
Fundamentally, this is a problem with how the reflection code is written. We currently infer some information about what the provider tries to set in state, then compare that to the schema to ensure that it matches what the schema expects. But we start with the type information of the data passed in.
In your example, you're using an untyped nil, which breaks that assumption because it has no type, so it falls through the switch statement. Wrapping it in a type assertion for an appropriate type for that attribute (e.g. *string(nil)) should, in theory, work. As should var val *string.
This isn't intuitive and is annoyingly verbose, though. And there's no reason it has to be this way.
One way to resolve this is to just check, in our reflection code, if the value is nil and return a null value if it is, short-circuiting the type reflection entirely. But I'm suspicious that untyped constants (string literals, numerical literals, etc.) will have the same problem.
A cleaner way may just be to flip our reflection code on it's head, starting with the type the schema defines and switching on that, checking that the data fits in it on a case-by-case basis, which should let us break down the untyped constants problem a little more cleanly.