hashicorp/terraform · error

invalid collection length: %s

Error message

invalid collection length: %s

What it means

Thrown by the `one()` collection function (OneFunc) when converting the computed length of a list or set into a Go int fails. After `val.Length()` returns a known cty value, gocty.FromCtyValue tries to decode it into an `int`; if that fails the value is not a valid integer. The source comment explicitly says this would be 'very strange' and 'would suggest a bug in cty', meaning this is an internal-invariant error rather than a normal validation failure. It surfaces to the Terraform user as an error from the `one(...)` call in HCL.

Source

Thrown at internal/lang/funcs/collection.go:463

		ty := val.Type()

		// Our parameter spec above doesn't set AllowUnknown or AllowNull,
		// so we can assume our top-level collection is both known and non-null
		// in here.

		switch {
		case ty.IsListType() || ty.IsSetType():
			lenVal := val.Length()
			if !lenVal.IsKnown() {
				return cty.UnknownVal(retType), nil
			}
			var l int
			err := gocty.FromCtyValue(lenVal, &l)
			if err != nil {
				// It would be very strange to get here, because that would
				// suggest that the length is either not a number or isn't
				// an integer, which would suggest a bug in cty.
				return cty.NilVal, fmt.Errorf("invalid collection length: %s", err)
			}
			switch l {
			case 0:
				return cty.NullVal(retType), nil
			case 1:
				var ret cty.Value
				// We'll use an iterator here because that works for both lists
				// and sets, whereas indexing directly would only work for lists.
				// Since we've just checked the length, we should only actually
				// run this loop body once.
				for it := val.ElementIterator(); it.Next(); {
					_, ret = it.Element()
				}
				return ret, nil
			}
		case ty.IsTupleType():
			etys := ty.TupleElementTypes()
			switch len(etys) {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Report this as a Terraform bug with the minimal .tf config that reproduces it, including the provider version producing the collection value.
  2. Inspect the value passed to `one()` (e.g. via `terraform console` running `length(var.x)`) to confirm whether it is a sane integer.
  3. Replace `one(x)` with an explicit length check (`x != null && length(x) == 1 ? x[0] : null`) to bypass the failing code path while the bug is investigated.
  4. Update or replace the provider/cty version that produces the anomalous collection length.

Example fix

// before
locals {
  item = one(data.buggy.thing.items)
}

// after: guard the value and surface a clearer message
locals {
  items = data.buggy.thing.items
  item  = length(local.items) == 1 ? local.items[0] : null
}
Defensive patterns

Strategy: validation

Validate before calling

// HCL: validate the collection is well-formed before calling one()
locals {
  items = var.list  # the list/set passed to one()
  ok    = can(length(local.items))
  item  = local.ok && length(local.items) <= 1 ? one(local.items) : null
}

Type guard

// HCL type guard: ensure arg is a list/set/tuple of <=1 element
output "checked" {
  value = can(one(var.x)) ? one(var.x) : null
}

Prevention

When it happens

Trigger: Calling `one(var.list)` or `one(local.set)` in a .tf file where the collection's runtime length value is produced by cty but is somehow not representable as a normal integer (e.g. a non-finite or non-numeric length coming out of a buggy provider output or expression). The length is marked IsKnown==true yet fails the integer decode.

Common situations: A provider returns a malformed collection whose length is not a finite integer; a cty-level corruption during expression evaluation; extremely rare in stock Terraform and almost always points to an upstream bug in cty or a custom provider. Not something a typical config mistake produces.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/11757b70380395dc. Report an issue: GitHub.