terraform-plugin-framework: Better error messaging for "unhandled {null,unknown} value"

When trying to reflect a state/plan value into a struct with plain Go types using Get(), the framework will throw an error if the value contains a Null or Unknown value. Developers receive a message saying “unhandled null value” or “unhandled unknown value” with little context.

Provider code

Example is from the framework-provider in terraform-provider-corner.

func (r resourceUserType) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
	return tfsdk.Schema{
		Attributes: map[string]tfsdk.Attribute{
			"name": {
				Type:     types.StringType,
				Required: true,
			},
			"id": {
				Type:     types.StringType,
				Computed: true,
			},
		},
	}, nil
}

type user struct {
	Name  string `tfsdk:"name"`
	Id    string `tfsdk:"id"`
}

func (r resourceUser) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) {
	var plan user
	diags := req.Plan.Get(ctx, &plan)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}

...

Config

resource "framework_user" "foo" {
  name = "Ford Prefect"
}

Output

When running terraform apply as part of an acc test:

--- FAIL: TestAccResourceUser (11.89s)
    resource_user_test.go:13: Step 1/1 error: Error running apply: exit status 1
        
        Error: Value Conversion Error
        
          with framework_user.foo,
          on terraform_plugin_test.tf line 2, in resource "framework_user" "foo":
           2: resource "framework_user" "foo" {
        
        An unexpected error was encountered trying to build a value. This is always
        an error in the provider. Please report the following to the provider
        developer:
        
        unhandled unknown value

Similarly, if the “id” attribute is instead marked as Optional: true and not set in the config, an “unhandled null value” error is thrown.

Conclusion

Consider logging the actual value that could not be converted.

Also, we may want to consider somehow extending the UnhandledNullAsEmpty and UnhandledUnknownAsEmpty reflect options into Get(), or perhaps an alternative “simple get” with these options set by default.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 7
  • Comments: 15 (6 by maintainers)

Commits related to this issue

Most upvoted comments

@bflad This seems to be a major issue and makes it impossible to work with non-required nested attributes. Is there any plan to fix this issue?