hashicorp/terraform · error
input list must not contain null string
Error message
input list must not contain null string
What it means
Thrown by `transpose()` (TransposeFunc) while iterating the inner list of a map value, when an element of that inner list is null. transpose() builds reversed string-keyed lists, so a null element (which would become a key) is rejected. The input map type is map(list(string)), but a null can still appear at runtime.
Solutions
- Compact each inner list to drop nulls: `{ for k, v in var.m : k => compact(v) }`.
- Filter at the source so inner lists never contain null.
- Use `[for s in v : s if s != null]` per inner list.
Example fix
// before
locals { t = transpose(var.tags) } # inner lists contain nulls
// after
locals { t = transpose({ for k, v in var.tags : k => compact(v) }) } Defensive patterns
Strategy: validation
Validate before calling
# HCL: compact inner lists to remove nulls
locals { t = transpose({ for k, v in var.m : k => compact(v) }) } Type guard
# HCL: filter nulls explicitly
locals { t = transpose({ for k, v in var.m : k => [for x in v : x if x != null] }) } Prevention
- Run compact() on inner lists before transpose().
- Constrain inner list element types to string at the variable declaration.
- Sanitize datasource output feeding transpose.
When it happens
Trigger: Calling transpose with a map whose list contains a null, e.g. `transpose({a = ["x", null]})`. Data sourced from a nullable nested attribute.
Common situations: A nested variable or datasource attribute producing nulls inside the inner lists. Optional inner elements resolving to null.
Related errors
- input must not contain null list
- input must be a map of lists of strings
- no non-null, non-empty-string arguments
- all arguments must have the same type
- argument must be a list or tuple
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/8f01654081f86d0a.
Report an issue: GitHub.
Appendix: source
Thrown at internal/lang/funcs/collection.go:591
RefineResult: refineNotNull,
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
inputMap := args[0]
if !inputMap.IsWhollyKnown() {
return cty.UnknownVal(retType), nil
}
outputMap := make(map[string]cty.Value)
tmpMap := make(map[string][]string)
for it := inputMap.ElementIterator(); it.Next(); {
inKey, inVal := it.Element()
if inVal.IsNull() {
return cty.MapValEmpty(cty.List(cty.String)), errors.New("input must not contain null list")
}
for iter := inVal.ElementIterator(); iter.Next(); {
_, val := iter.Element()
if val.IsNull() {
return cty.MapValEmpty(cty.List(cty.String)), errors.New("input list must not contain null string")
}
if !val.Type().Equals(cty.String) {
return cty.MapValEmpty(cty.List(cty.String)), errors.New("input must be a map of lists of strings")
}
outKey := val.AsString()
if _, ok := tmpMap[outKey]; !ok {
tmpMap[outKey] = make([]string, 0)
}
outVal := tmpMap[outKey]
outVal = append(outVal, inKey.AsString())
sort.Strings(outVal)
tmpMap[outKey] = outVal
}
}
for outKey, outVal := range tmpMap {
values := make([]cty.Value, 0)View on GitHub (pinned to d32a084675)