diff --git a/internal/lang/function_results.go b/internal/lang/function_results.go index 6d4f97e700d1..2b7b23afb8a7 100644 --- a/internal/lang/function_results.go +++ b/internal/lang/function_results.go @@ -51,6 +51,16 @@ func (f *FunctionResults) CheckPrior(name string, args []cty.Value, result cty.V // CheckPriorProvider compares the provider function call against any cached // results, and returns an error if the result does not match a prior call. func (f *FunctionResults) CheckPriorProvider(provider addrs.Provider, name string, args []cty.Value, result cty.Value) error { + // Don't cache unknown values. We could technically store types and + // refinements for validation, but we don't currently have a way to + // serialize those in the plan. Unknowns are also handled much more + // gracefully throughout the evaluation system, whereas invalid data is + // harder to trace back to the source since it's usually only visible due to + // unexpected side-effects. + if !result.IsKnown() { + return nil + } + argSum := sha256.New() if !provider.IsZero() { diff --git a/internal/lang/function_results_test.go b/internal/lang/function_results_test.go index da5715738bd1..56e44244c64a 100644 --- a/internal/lang/function_results_test.go +++ b/internal/lang/function_results_test.go @@ -72,7 +72,7 @@ func TestFunctionCache(t *testing.T) { result: cty.False, }, // result changed from unknown => false - expectErr: true, + expectErr: false, }, { first: testCall{ @@ -172,6 +172,9 @@ func TestFunctionCache(t *testing.T) { if err != nil && !test.expectErr { t.Fatal(err) } + if err == nil && test.expectErr { + t.Fatal("expected error") + } // reload the data to ensure we validate identically newResults := NewFunctionResultsTable(results.GetHashes())