{"record":{"id":"84f16d117815877c","repo":"hashicorp/terraform","slug":"cannot-search-an-empty-list","errorCode":null,"errorMessage":"cannot search an empty list","messagePattern":"cannot search an empty list","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lang/funcs/collection.go","lineNumber":201,"sourceCode":"\t\t},\n\t\t{\n\t\t\tName: \"value\",\n\t\t\tType: cty.DynamicPseudoType,\n\t\t},\n\t},\n\tType:         function.StaticReturnType(cty.Number),\n\tRefineResult: refineNotNull,\n\tImpl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {\n\t\tif !(args[0].Type().IsListType() || args[0].Type().IsTupleType()) {\n\t\t\treturn cty.NilVal, errors.New(\"argument must be a list or tuple\")\n\t\t}\n\n\t\tif !args[0].IsKnown() {\n\t\t\treturn cty.UnknownVal(cty.Number), nil\n\t\t}\n\n\t\tif args[0].LengthInt() == 0 { // Easy path\n\t\t\treturn cty.NilVal, errors.New(\"cannot search an empty list\")\n\t\t}\n\n\t\tfor it := args[0].ElementIterator(); it.Next(); {\n\t\t\ti, v := it.Element()\n\t\t\teq, err := stdlib.Equal(v, args[1])\n\t\t\tif err != nil {\n\t\t\t\treturn cty.NilVal, err\n\t\t\t}\n\t\t\tif !eq.IsKnown() {\n\t\t\t\treturn cty.UnknownVal(cty.Number), nil\n\t\t\t}\n\t\t\tif eq.True() {\n\t\t\t\treturn i, nil\n\t\t\t}\n\t\t}\n\t\treturn cty.NilVal, errors.New(\"item not found\")\n\n\t},","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/lang/funcs/collection.go#L183-L219","documentation":"Thrown by IndexFunc.Impl when the list argument is known but has length 0. There is nothing to search, so the function fails fast rather than returning a misleading result.","triggerScenarios":"index(local.empty_list, \"x\") where the list resolved to []; index(split(\",\", var.s), token) when var.s is empty so split returns a single empty element or [] in some paths.","commonSituations":"A list that is conditionally empty (filtered to nothing); an upstream for_each that produced no items; optional input omitted.","solutions":["Guard the call: use a conditional or can() to skip when length is 0.","Ensure the list is non-empty before invoking index().","Provide a default element so the list always has content."],"exampleFix":"# before\nlocals { i = index(var.items, \"x\") }   # var.items may be []\n# after\nlocals {\n  i = length(var.items) > 0 ? index(var.items, \"x\") : -1\n}","handlingStrategy":"validation","validationCode":"# only call index when the list is non-empty\nlocals {\n  i = length(var.items) > 0 ? index(var.items, \"x\") : -1\n}","typeGuard":"locals {\n  non_empty = try(length(var.items) > 0, false)\n  i         = local.non_empty ? index(var.items, \"x\") : -1\n}","tryCatchPattern":"locals { i = try(index(var.items, \"x\"), -1) }","preventionTips":["Check length(list) > 0 before index().","Filter/compact lists upstream so emptiness is impossible.","Prefer contains() when you only need membership, not position."],"tags":["hcl","function","index","validation"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}