diff --git a/plans/objchange/compatible.go b/plans/objchange/compatible.go index 8b7ef43fd..8a74c07fe 100644 --- a/plans/objchange/compatible.go +++ b/plans/objchange/compatible.go @@ -84,7 +84,7 @@ func assertObjectCompatible(schema *configschema.Block, planned, actual cty.Valu // whether there are dynamically-typed attributes inside. However, // both support a similar-enough API that we can treat them the // same for our purposes here. - if !plannedV.IsKnown() || plannedV.IsNull() || actualV.IsNull() { + if !plannedV.IsKnown() || !actualV.IsKnown() || plannedV.IsNull() || actualV.IsNull() { continue } diff --git a/plans/objchange/compatible_test.go b/plans/objchange/compatible_test.go index e8af5458b..2841ec26b 100644 --- a/plans/objchange/compatible_test.go +++ b/plans/objchange/compatible_test.go @@ -1135,6 +1135,32 @@ func TestAssertObjectCompatible(t *testing.T) { }), nil, }, + { + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "block": { + Nesting: configschema.NestingList, + Block: configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "block": cty.EmptyObjectVal, + }), + cty.ObjectVal(map[string]cty.Value{ + "block": cty.UnknownVal(cty.List(cty.Object(map[string]cty.Type{ + "foo": cty.String, + }))), + }), + nil, + }, } for i, test := range tests {