fix: preserve empty list vs null distinction for optional list attributes
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful

The API returns null for empty arrays, but OpenTofu requires that the
state match the plan exactly — an empty list [] in the plan must remain
[] in the state, not become null. This caused "inconsistent result after
apply" errors on every resource with empty optional list fields like
mutable_patterns and ban_tags.
This commit is contained in:
2026-06-21 18:42:14 +10:00
parent 7c94f06be6
commit d9d8cc7b6d
3 changed files with 67 additions and 3 deletions
+12 -1
View File
@@ -16,7 +16,7 @@ func listToStrings(ctx context.Context, l types.List) []string {
}
func stringsToList(ctx context.Context, ss []string) types.List {
if len(ss) == 0 {
if ss == nil {
return types.ListNull(types.StringType)
}
elems := make([]types.String, len(ss))
@@ -26,3 +26,14 @@ func stringsToList(ctx context.Context, ss []string) types.List {
list, _ := types.ListValueFrom(ctx, types.StringType, elems)
return list
}
// preserveListNullEmptySemantics keeps the prior null/empty distinction when
// the API returns null for a field that was previously an empty list.
// Without this, OpenTofu reports "inconsistent result after apply" because
// the plan/state had [] but the provider returned null.
func preserveListNullEmptySemantics(prior, current types.List) types.List {
if current.IsNull() && !prior.IsNull() && len(prior.Elements()) == 0 {
return prior
}
return current
}