"Error: Provider produced inconsistent result after apply" for optional & computed field

Hi there,

I am getting this error during Create and Update operations with my custom terraform provider created using the terraform-plugin-framework:

╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to <resource-type>.<resource-name>, provider "provider[<provider-name>]" produced an unexpected new value:
│ .spec["resource-name"].maximum: was cty.NumberIntVal(5), but now cty.NumberIntVal(12).
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

The maximum field is marked as optional & computed. It’s a field that the user can choose to set but the upstream API that’s called in the Create & Update functions can set it to a different field than the user selected based on the upstream service’s internal logic.

Ie due to some other configs the ‘maximum’ field has to be atleast 12, so if the user tries to set ‘maximum’ to 5, the upstream API will automatically use 12 and return that in the updated state. Thus it looks like the plan and state have different values, which is okay in this case.

In the case the user tries to set ‘maximum’ to 12 or above this error wont appear because the final set will correspond to the plan. Note: 12 is not a default, just an example I’m using.

I don’t want to add any PlanModifiers for this field that mimic the logic of setting the ‘maximum’ field in the upstream API as that logic can change in the future, and ‘maximum’ is just one of the fields I am having this issue with.

Hey there @abdulelrahwan :wave:,

So you’re running into a data consistency error being enforced by Terraform, the full set of rules/lifecycle is described here, but I’ll pull out the important bits to this thread to help guide what you can do here.

During plan:

Any attribute that was non-null in the configuration must either preserve the exact configuration value or return the corresponding attribute value from the prior state.

Currently, your logic is planning the config value, which means that you’re not breaking this rule right now. Although it’s important to note this, as it would be considered invalid for a plan modifier to plan a different value (12 from the API) when the user has entered a config value (5).

During apply:

Any attribute that had a known value in the Final Planned State must have an identical value in the new state.

This is the rule that’s being broken currently, so if you plan 5 from the configuration, it’s invalid to return 12 during apply (create/update methods).


Some potential ways forward, depending on how you’d like the user experience to be:

  • You could introduce validation during plan modification to return an error diagnostic describing to the user if they have entered a configuration value that exceeds the allowed maximum value defined by the API. In that scenario, the user would then have to modify their configuration to be valid.
  • You could modify your schema to model your API’s behavior, by having a configuration-only attribute requested_maximum and then a computed-only attribute actual_maximum that the user could reference.