hashicorp/terraform · error
all arguments must have the same type
Error message
all arguments must have the same type
What it means
Thrown by CoalesceFunc.Type (the HCL coalesce() builtin). coalesce() must return a single type, so all arguments are passed through convert.UnifyUnsafe; if they cannot be unified it reports that all arguments must share a type.
Source
Thrown at internal/lang/funcs/collection.go:152
// stdlib and modified so that it returns the first *non-empty* non-null element
// from a sequence, instead of merely the first non-null.
var CoalesceFunc = function.New(&function.Spec{
Params: []function.Parameter{},
VarParam: &function.Parameter{
Name: "vals",
Type: cty.DynamicPseudoType,
AllowUnknown: true,
AllowDynamicType: true,
AllowNull: true,
},
Type: func(args []cty.Value) (ret cty.Type, err error) {
argTypes := make([]cty.Type, len(args))
for i, val := range args {
argTypes[i] = val.Type()
}
retType, _ := convert.UnifyUnsafe(argTypes)
if retType == cty.NilType {
return cty.NilType, errors.New("all arguments must have the same type")
}
return retType, nil
},
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
}
View on GitHub (pinned to c9def3e214)
Solutions
- Normalize each argument to the desired type before calling: coalesce(tostring(var.a), tostring(var.b)).
- Pick arguments that are inherently the same type.
- Use try() with explicit conversions when types are uncertain.
Example fix
# before
locals { name = coalesce(var.display_name, var.id) } # string vs number
# after
locals { name = coalesce(var.display_name, tostring(var.id)) } Defensive patterns
Strategy: type-guard
Validate before calling
# normalize all coalesce args to one type beforehand
locals { name = coalesce(tostring(var.a), tostring(var.b)) } Type guard
# guard: unify types before calling coalesce
locals {
a_str = try(tostring(var.a), null)
b_str = try(tostring(var.b), null)
name = coalesce(a_str, b_str)
} Try / catch
locals { name = try(coalesce(tostring(var.a), tostring(var.b)), "default") } Prevention
- Declare variables with explicit types so coalesce candidates naturally match.
- Convert at the source (tostring/tonumber) instead of mixing raw values.
- Unit-test locals with sentinel values to catch type drift.
When it happens
Trigger: Mixing types in one call: coalesce("a", 1), coalesce([], {}), coalesce(var.s, var.n) where one is string and one number.
Common situations: Coalescing a string default with a numeric value, or two differently-typed optional variables; forgetting that '0' vs 0 differ in type.
Related errors
- argument must be a string, a collection type, or a structura
- no non-null, non-empty-string arguments
- argument must be a list or tuple
- keys and searchset must be of the same type
- input must be a map of lists of strings
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/1368fd7abd8cc4e6.
Report an issue: GitHub.