hashicorp/terraform · error
length of keys and values should be equal
Error message
length of keys and values should be equal
What it means
Thrown by `matchkeys()` (MatchkeysFunc) in its Impl when `values` (1st arg) and `keys` (2nd arg) have different lengths. matchkeys pairs values[i] with keys[i] positionally, so the two lists must have equal length; a mismatch is a logic error and the function returns an empty list plus this error.
Solutions
- Ensure values and keys are derived from the same source so their lengths stay in sync.
- Validate length equality before calling: guard with `length(var.values) == length(var.keys)`.
- Restructure as a single list of objects {value=..., key=...} so pairing cannot drift.
Example fix
// before
locals { r = matchkeys(var.names, var.ids, ["prod"]) } # names and ids differ in length
// after
locals {
pairs = [for i, n in var.names : { name = n, id = var.ids[i] }] # built from one source
r = [for p in local.pairs : p.name if contains(["prod"], p.id)]
} Defensive patterns
Strategy: validation
Validate before calling
# HCL: assert equal length before matchkeys
locals {
ok = length(var.values) == length(var.keys)
r = local.ok ? matchkeys(var.values, var.keys, var.searchset) : []
} Type guard
# HCL: derive both from one source list of objects
locals {
pairs = [for p in var.records : { value = p.value, key = p.key }]
} Prevention
- Build values and keys from the same for-expression so lengths stay in sync.
- Add a length-equality check before matchkeys.
- Prefer a single list of objects over two parallel lists.
When it happens
Trigger: Calling `matchkeys(values, keys, searchset)` where len(values) != len(keys). One list was filtered or extended independently of the other.
Common situations: Two parallel lists maintained in separate locals/blocks that drifted out of sync. A comprehension that built values from a superset of the source used for keys.
Related errors
- keys and searchset must be of the same type
- all arguments must have the same type
- argument must be a list or tuple
- argument must be a string, a collection type, or a…
- cannot search an empty list
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/02785d499d6ada09.
Report an issue: GitHub.
Appendix: source
Thrown at internal/lang/funcs/collection.go:365
},
},
Type: func(args []cty.Value) (cty.Type, error) {
ty, _ := convert.UnifyUnsafe([]cty.Type{args[1].Type(), args[2].Type()})
if ty == cty.NilType {
return cty.NilType, errors.New("keys and searchset must be of the same type")
}
// the return type is based on args[0] (values)
return args[0].Type(), nil
},
RefineResult: refineNotNull,
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
if !args[0].IsKnown() {
return cty.UnknownVal(cty.List(retType.ElementType())), nil
}
if args[0].LengthInt() != args[1].LengthInt() {
return cty.ListValEmpty(retType.ElementType()), errors.New("length of keys and values should be equal")
}
output := make([]cty.Value, 0)
values := args[0]
// Keys and searchset must be the same type.
// We can skip error checking here because we've already verified that
// they can be unified in the Type function
ty, _ := convert.UnifyUnsafe([]cty.Type{args[1].Type(), args[2].Type()})
keys, _ := convert.Convert(args[1], ty)
searchset, _ := convert.Convert(args[2], ty)
// if searchset is empty, return an empty list.
if searchset.LengthInt() == 0 {
return cty.ListValEmpty(retType.ElementType()), nil
}
if !values.IsWhollyKnown() || !keys.IsWhollyKnown() {View on GitHub (pinned to d32a084675)