Error setting state with computed MapnestedAttribute

Hi,

I am developing a terraform provider using terraform-plugin-framework. I have a client file which reach vendor api and it returns nested json object after successful resource creation. i am using below 3 structs to convert the json to struct and passing it to the provider file.

type domainAuthDNS struct {
	DKIM1        domainAuthDNSRecord `json:"dkim1,omitempty"`
	DKIM2        domainAuthDNSRecord `json:"dkim2,omitempty"`
	MailCNAME    domainAuthDNSRecord `json:"mail_cname,omitempty"`
	DKIM         domainAuthDNSRecord `json:"dkim,omitempty"`
	MailServer   domainAuthDNSRecord `json:"mail_server,omitempty"`
	SubDomainSPF domainAuthDNSRecord `json:"subdomain_spf,omitempty"`
}

type domainAuthDNSRecord struct {
	Valid bool   `json:"valid,omitempty"`
	Type  string `json:"type,omitempty"`
	Host  string `json:"host,omitempty"`
	Data  string `json:"data,omitempty"`
}

type domainAuth struct {
	Domain             string        `json:"domain,omitempty"`
	CustomDkimSelector string        `json:"custom_dkim_selector"`
	DNS                domainAuthDNS `json:"dns,omitempty"`
	UserName           string        `json:"username,omitempty"`
	AutomaticSecurity  bool          `json:"automatic_security,omitempty"`
	Valid              bool          `json:"valid,omitempty"`
	Id                 int32         `json:"id,omitempty"`
}

Now in provider file i have the below structs defined with MapNestedattribute schema.

type DomainauthResourceModel struct {
	ID            types.Int64               `tfsdk:"id"`
	UserId        types.Int64               `tfsdk:"user_id"`
	Valid         types.Bool                `tfsdk:"valid"`
	DNSDetails    map[string]DomainAuthKeys `tfsdk:"dns"`
}

type DomainAuthKeys struct {
	DKIM         DomainAuthRecord `tfsdk:"dkim"`
	MailServer   DomainAuthRecord `tfsdk:"mail_server"`
	SubDomainSPF DomainAuthRecord `tfsdk:"subdomain_spf"`
	DKIM2        DomainAuthRecord `tfsdk:"dkim2"`
	MailCNAME    DomainAuthRecord `tfsdk:"mail_cname"`
	DKIM1        DomainAuthRecord `tfsdk:"dkim1"`
}

type DomainAuthRecord struct {
	Valid types.Bool   `tfsdk:"valid"`
	Types types.String `tfsdk:"types"`
	Host  types.String `tfsdk:"host"`
	Data  types.String `tfsdk:"data"`
}

below is the create code section code which i am using to store on state

var newstate DomainauthResourceModel
	diags := req.Plan.Get(ctx, &newstate)
	if diags.HasError() {
		resp.Diagnostics.AddError(
			"Error reading domain authentication",
			fmt.Sprintf("Error reading domain authentication: %s", diags.Errors()),
		)
		return
	}


inputmap := make(map[string]DomainAuthKeys, 0)
	inputmap["dns"] = DomainAuthKeys{
		DKIM: DomainAuthRecord{
			Valid: types.BoolValue(newItem.DNSDetails.DKIM.Valid),
			Types: types.StringValue(newItem.DNSDetails.DKIM.Type),
			Host:  types.StringValue(newItem.DNSDetails.DKIM.Host),
			Data:  types.StringValue(newItem.DNSDetails.DKIM.Data),
		},
		MailServer: DomainAuthRecord{
			Valid: types.BoolValue(newItem.DNSDetails.MailServer.Valid),
			Types: types.StringValue(newItem.DNSDetails.MailServer.Type),
			Host:  types.StringValue(newItem.DNSDetails.MailServer.Host),
			Data:  types.StringValue(newItem.DNSDetails.MailServer.Data),
		},
	}

	newstate = DomainauthResourceModel{
		ID:            types.Int64Value(newItem.ID),
		UserId:        types.Int64Value(newItem.UserId),
		DNSDetails:    inputmap,
	}

i could understand something is wrong, but couldn’t get right direction. Could someone please help me to overcome the below error.

Error: Error reading domain authentication
││
│ Error reading domain authentication: [{{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:

│ Received unknown value, however the target type cannot handle unknown values. Use the corresponding types package type or
│ a custom type that handles unknown values.

│ Path: dns
│ Target Type: map[string]provider.DomainAuthKeys
│ Suggested Type: basetypes.MapValue Value Conversion Error} {[dns]}}]

Hey there @sikaleel87 :wave: , welcome to the Hashi discuss forum!

The error you’re running into is a result of the data models that are tagged with tfsdk, specifically DNSDetails. (the underlying DomainAuthKeys will suffer from the same problem)

The error is occurring because native Go structs don’t have a concept of unknown, while these maps and objects you’ve defined can be unknown (say if one of the values is provided by another resource that doesn’t exist yet).

The solution is to adjust your data model to utilize the built-in Framework types, which you can then check if they are unknown before performing operations on them, types.Map and types.Object.

type DomainauthResourceModel struct {
	ID            types.Int64               `tfsdk:"id"`
	UserId        types.Int64               `tfsdk:"user_id"`
	Valid         types.Bool                `tfsdk:"valid"`
	DNSDetails    types.Map                 `tfsdk:"dns"`
}

type DomainAuthKeys struct {
	DKIM         types.Object `tfsdk:"dkim"`
	MailServer   types.Object `tfsdk:"mail_server"`
	SubDomainSPF types.Object `tfsdk:"subdomain_spf"`
	DKIM2        types.Object `tfsdk:"dkim2"`
	MailCNAME    types.Object `tfsdk:"mail_cname"`
	DKIM1        types.Object `tfsdk:"dkim1"`
}

type DomainAuthRecord struct {
	Valid types.Bool   `tfsdk:"valid"`
	Types types.String `tfsdk:"types"`
	Host  types.String `tfsdk:"host"`
	Data  types.String `tfsdk:"data"`
}

We’ve recently revamped the docs for framework built-in types, so check out those for examples on accessing/setting values with types.Map and types.Object.

Thank you so much for the reply @austin.valle . I was able to alter them in the way i needed and all works well now. sorry for the delay in response.

1 Like