{"record":{"id":"11757b70380395dc","repo":"hashicorp/terraform","slug":"invalid-collection-length-s","errorCode":null,"errorMessage":"invalid collection length: %s","messagePattern":"invalid collection length: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lang/funcs/collection.go","lineNumber":463,"sourceCode":"\t\tty := val.Type()\n\n\t\t// Our parameter spec above doesn't set AllowUnknown or AllowNull,\n\t\t// so we can assume our top-level collection is both known and non-null\n\t\t// in here.\n\n\t\tswitch {\n\t\tcase ty.IsListType() || ty.IsSetType():\n\t\t\tlenVal := val.Length()\n\t\t\tif !lenVal.IsKnown() {\n\t\t\t\treturn cty.UnknownVal(retType), nil\n\t\t\t}\n\t\t\tvar l int\n\t\t\terr := gocty.FromCtyValue(lenVal, &l)\n\t\t\tif err != nil {\n\t\t\t\t// It would be very strange to get here, because that would\n\t\t\t\t// suggest that the length is either not a number or isn't\n\t\t\t\t// an integer, which would suggest a bug in cty.\n\t\t\t\treturn cty.NilVal, fmt.Errorf(\"invalid collection length: %s\", err)\n\t\t\t}\n\t\t\tswitch l {\n\t\t\tcase 0:\n\t\t\t\treturn cty.NullVal(retType), nil\n\t\t\tcase 1:\n\t\t\t\tvar ret cty.Value\n\t\t\t\t// We'll use an iterator here because that works for both lists\n\t\t\t\t// and sets, whereas indexing directly would only work for lists.\n\t\t\t\t// Since we've just checked the length, we should only actually\n\t\t\t\t// run this loop body once.\n\t\t\t\tfor it := val.ElementIterator(); it.Next(); {\n\t\t\t\t\t_, ret = it.Element()\n\t\t\t\t}\n\t\t\t\treturn ret, nil\n\t\t\t}\n\t\tcase ty.IsTupleType():\n\t\t\tetys := ty.TupleElementTypes()\n\t\t\tswitch len(etys) {","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/lang/funcs/collection.go#L445-L481","documentation":"one() function internal error: after computing the collection length and confirming it is known, gocty.FromCtyValue fails to convert the length cty number into a Go int. The code comment notes this is essentially impossible under normal operation -- it would indicate a bug in cty itself (length returned non-number/non-integer). End users effectively never see this; it surfaces only if a custom cty value breaks the length contract.","triggerScenarios":"Calling one() on a list/set whose Length() returns a value that is not convertible to int (e.g. a number marked in a way that disrupts FromCtyValue, or a hand-constructed pathological cty value).","commonSituations":"Effectively unreachable in normal HCL; would only appear with custom function wrappers feeding malformed cty values into the standard one() function.","solutions":["Treat this as a Terraform/cty bug: report it with the exact configuration and cty version.","Verify the input to one() is a plain list/set (not a marked or proxy value).","As a workaround, replace one() with explicit indexing: element[0]."],"exampleFix":"// before\nlocals { x = one(var.list) } // triggers pathological case\n\n// after (workaround)\nlocals { x = length(var.list) == 1 ? var.list[0] : null }","handlingStrategy":"try-catch","validationCode":"// Ensure the input is a plain list/set before calling one().\nlocals { ok = can(one(var.list)) ? one(var.list) : null }","typeGuard":null,"tryCatchPattern":"v, err := funcs.OneFunc.Call([]cty.Value{listVal})\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid collection length\") {\n        // treat as a cty/terraform bug; report upstream\n    }\n}\n","preventionTips":["Pass plain list/set values to one().","Avoid marked or proxy cty values that could break Length().","If this fires, suspect a cty bug and report it."],"tags":["terraform","hcl-functions","one","cty","internal-bug"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}