diff --git a/hclsyntax/expression_template.go b/hclsyntax/expression_template.go index a0dc7c22..31901720 100644 --- a/hclsyntax/expression_template.go +++ b/hclsyntax/expression_template.go @@ -250,7 +250,21 @@ func (e *TemplateWrapExpr) walkChildNodes(w internalWalkFunc) { } func (e *TemplateWrapExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { - return e.Wrapped.Value(ctx) + val, diags := e.Wrapped.Value(ctx) + + // If the single interpolation result is null, we need to return the same + // error as we would for a TemplateExpr with a null part. + if val.IsNull() { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid template interpolation value", + Detail: "The expression result is null. Cannot include a null value in a string template.", + Subject: e.Range().Ptr(), + Expression: e.Wrapped, + EvalContext: ctx, + }) + } + return val, diags } func (e *TemplateWrapExpr) Range() hcl.Range { diff --git a/hclsyntax/expression_template_test.go b/hclsyntax/expression_template_test.go index 92c11afe..50f654da 100644 --- a/hclsyntax/expression_template_test.go +++ b/hclsyntax/expression_template_test.go @@ -403,6 +403,26 @@ trim`, cty.UnknownVal(cty.String).Mark("sensitive").Refine().NotNull().StringPrefixFull("test_").NewValue(), 0, }, + { // template with a single wrapped expr that is null + `${hello}`, + &hcl.EvalContext{ + Variables: map[string]cty.Value{ + "hello": cty.NullVal(cty.String), + }, + }, + cty.NullVal(cty.String), + 1, // error about null value + }, + { + `foo ${hello}`, + &hcl.EvalContext{ + Variables: map[string]cty.Value{ + "hello": cty.NullVal(cty.String), + }, + }, + cty.StringVal("foo "), + 1, // error about null value + }, } for _, test := range tests {