hashicorp/terraform · error
no non-null, non-empty-string arguments
Error message
no non-null, non-empty-string arguments
What it means
Thrown by CoalesceFunc.Impl after iterating all arguments: none was non-null and (for strings) non-empty, so there is nothing to return. coalesce() returns the first usable value, and here every candidate was rejected.
Source
Thrown at internal/lang/funcs/collection.go:173
},
RefineResult: refineNotNull,
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
for _, argVal := range args {
// We already know this will succeed because of the checks in our Type func above
argVal, _ = convert.Convert(argVal, retType)
if !argVal.IsKnown() {
return cty.UnknownVal(retType), nil
}
if argVal.IsNull() {
continue
}
if retType == cty.String && argVal.RawEquals(cty.StringVal("")) {
continue
}
return argVal, nil
}
return cty.NilVal, errors.New("no non-null, non-empty-string arguments")
},
})
// IndexFunc constructs a function that finds the element index for a given value in a list.
var IndexFunc = function.New(&function.Spec{
Params: []function.Parameter{
{
Name: "list",
Type: cty.DynamicPseudoType,
},
{
Name: "value",
Type: cty.DynamicPseudoType,
},
},
Type: function.StaticReturnType(cty.Number),
RefineResult: refineNotNull,
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {View on GitHub (pinned to c9def3e214)
Solutions
- Add a concrete non-empty fallback as the last argument.
- Replace nulls upstream so at least one argument is valid.
- Use try() with a hardcoded default if you need guaranteed output.
Example fix
# before
locals { tag = coalesce(var.env_tag, var.default_tag) } # both null -> error
# after
locals { tag = coalesce(var.env_tag, var.default_tag, "untagged") } Defensive patterns
Strategy: validation
Validate before calling
# guarantee at least one usable value with a concrete fallback
locals { tag = coalesce(var.a, var.b, "untagged") } Type guard
# check that at least one candidate is non-empty before coalesce
locals {
has_value = anytrue([for v in [var.a, var.b] : try(length(tostring(v)) > 0, false)])
tag = local.has_value ? coalesce(var.a, var.b) : "untagged"
} Try / catch
locals { tag = try(coalesce(var.a, var.b), "untagged") } Prevention
- Always end coalesce chains with a literal default.
- Default optional variables to a real value, not null/empty.
- Use precondition checks to fail fast with a clear message when all inputs are empty.
When it happens
Trigger: coalesce(null, null, ""), coalesce(var.optional_a, var.optional_b) when both are unset and default to null/empty, or coalesce() with no arguments.
Common situations: All optional inputs genuinely absent; variables default to null or empty string; chained lookups that all miss.
Related errors
- all arguments must have the same type
- cannot search an empty list
- item not found
- length of keys and values should be equal
- input must not contain null list
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/b9fd96ba236ed77e.
Report an issue: GitHub.