## TL;DR

You put a null (or a non-string like an object) inside `${ ... }`. String templates only accept strings. Guard with a default: `"${var.name != null ? var.name : ""}"` or `coalesce(var.name, "")`, then re-plan.

## The error

```text
Error: Invalid template interpolation value

  on main.tf line 6, in locals:
   6:   templated = "foo=${var.foo}"
     ├────────────────
     │ var.foo is null

The expression result is null. Cannot include a null value in a string
template.
```

Another common shape:

```text
Error: Invalid template interpolation value: Cannot include the given value in a string template: string required.
```

## Steps to fix

1. Find the interpolation the error names and check the value: the `├` line tells you it is null or an object.
   - Expected: you see `var.foo is null` or similar.
2. Decide what the string should be when the value is absent. Usual fixes:
   ```hcl
   templated = "foo=${coalesce(var.foo, "default")}"
   ```
   or for preconditions/error messages, render nulls explicitly:
   ```hcl
   error_message = "tag must match spec (got ${coalesce(local.user_tag, "[unset]")})."
   ```
   - Expected: the template always receives a string.
3. If you interpolated a whole object (`"${module.foo}"`), pick the specific attribute instead (`module.foo.id`).
   - Expected: scalar value in the template.
4. Run `terraform validate` then `plan`.
   - Expected: both pass.

## When to use this

- `plan`/`validate` fails with `Invalid template interpolation value` on a `${ }` sequence, very often inside `error_message` strings of preconditions or in `templatefile` vars.

## When NOT to use this

- `Invalid function argument` is a function-call type problem, not a template problem. `terraform validate` does NOT catch this (it reports success while plan fails), so always re-plan after fixing.

## Compatibility

- All Terraform versions. Note: `validate` passes while `plan` fails for this error, a known sharp edge.

## Root cause

String templates require every interpolated value to be a string (or null-free convertible). Terraform renders `error_message` before evaluating the condition, so even a passing precondition dies if its message interpolates a null. Optional variables default to null, which is why this bites optional inputs so often.

## Edge cases

- `nullable = false` on the variable prevents null at the boundary, but the error can still come from locals or data sources.
- `join()` with a null in the list fails the same way; filter nulls first.
- In `templatefile`, pass pre-stringified values (`tostring()`) rather than raw objects.