hashicorp/terraform · error
keys and searchset must be of the same type
Error message
keys and searchset must be of the same type
What it means
Thrown by the `matchkeys()` function (MatchkeysFunc) in its Type callback when the element types of `keys` (2nd arg) and `searchset` (3rd arg) cannot be unified via convert.UnifyUnsafe. matchkeys joins keys against searchset by equality, so their element types must be compatible; if UnifyUnsafe returns NilType the type check fails before evaluation.
Solutions
- Make keys and searchset the same element type, or convertible types (e.g. both list(string)).
- Add explicit conversion: `matchkeys(var.values, tolist(var.keys), [tostring(var.target)])`.
- Re-type the upstream variables so both sides agree.
Example fix
// before
locals { r = matchkeys(var.values, var.keys, [var.target_id]) } # keys=list(string), target_id=number
// after
locals { r = matchkeys(var.values, var.keys, [tostring(var.target_id)]) } Defensive patterns
Strategy: validation
Validate before calling
# HCL: unify types before matchkeys
locals {
keys2 = [for k in var.keys : tostring(k)]
searchset2 = [for s in var.searchset : tostring(s)]
r = matchkeys(var.values, local.keys2, local.searchset2)
} Type guard
# HCL: assert same element type
locals { ok = length(var.keys) == 0 || try(var.keys[0], null) == try(var.searchset[0], null) } Prevention
- Type keys and searchset identically at the variable declaration.
- Convert both sides with to{string,number}() before matchkeys.
- Validate element-type equality in CI via terraform validate.
When it happens
Trigger: Calling `matchkeys(values, keys, searchset)` where keys and searchset hold different element types, e.g. keys is list(string) and searchset is list(number).
Common situations: Building a lookup where keys were typed as strings (e.g. "1") but searchset as numbers (1), or vice versa. Inconsistent typing between two data sources joined by matchkeys.
Related errors
- all arguments must have the same type
- length of keys and values should be equal
- 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/c2ee41ee8fd074a1.
Report an issue: GitHub.
Appendix: source
Thrown at internal/lang/funcs/collection.go:352
var MatchkeysFunc = function.New(&function.Spec{
Params: []function.Parameter{
{
Name: "values",
Type: cty.List(cty.DynamicPseudoType),
},
{
Name: "keys",
Type: cty.List(cty.DynamicPseudoType),
},
{
Name: "searchset",
Type: cty.List(cty.DynamicPseudoType),
},
},
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]
View on GitHub (pinned to d32a084675)