hashicorp/terraform · error

wrong number of values for

Error message

wrong number of values for %q in state: got %d, but need %d

What it means

Returned by hcl2ValueFromFlatmapTuple when the count sentinel parses as an integer but does not equal len(etys) — the declared tuple element type count. Because tuple types are positional with a fixed arity, a mismatch between the persisted count and the schema's expected element count means the state does not conform to the schema and decoding cannot proceed unambiguously.

Solutions

  1. Confirm the schema's tuple element type count matches the count sentinel in state; if the schema legitimately changed arity, write a state upgrader.
  2. Restore state from a backup written under the matching schema version.
  3. Pin the provider version so schema and state evolve together, then upgrade deliberately.
  4. If the tuple is actually variable-length, model it as a list (cty.List) rather than a positional tuple.

Example fix

// conceptual
// before: tuple type with 2 element types, state count sentinel = 3
// after: align — either update schema to declare 3 element types, or write
//        a state v0->v1 upgrader that reshapes the stored value to 2 slots.
Defensive patterns

Strategy: validation

Validate before calling

func tupleCountMatchesArity(m map[string]string, prefix string, arity int) bool {
    s, ok := m[prefix+"#"]
    if !ok { return true }
    n, err := strconv.Atoi(s)
    if err != nil { return false }
    return n == arity
}

Prevention

When it happens

Trigger: A tuple-typed attribute whose schema declares N element types but whose flatmap count sentinel holds M != N. Reached during state read or plan-time diff when the schema and state disagree on tuple width.

Common situations: Schema change that added/removed tuple positions without a corresponding state upgrader; state written against an older provider version; merging state from incompatible provider versions.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/b2ae01d15c4295f0. Report an issue: GitHub.

Appendix: source

Thrown at internal/configs/hcl2shim/flatmap.go:240

	listName := strings.TrimRight(prefix, ".")
	if m[listName] == UnknownVariableValue {
		return cty.UnknownVal(cty.Tuple(etys)), nil
	}

	countStr, exists := m[prefix+"#"]
	if !exists {
		return cty.NullVal(cty.Tuple(etys)), nil
	}
	if countStr == UnknownVariableValue {
		return cty.UnknownVal(cty.Tuple(etys)), nil
	}

	count, err := strconv.Atoi(countStr)
	if err != nil {
		return cty.DynamicVal, fmt.Errorf("invalid count value for %q in state: %s", prefix, err)
	}
	if count != len(etys) {
		return cty.DynamicVal, fmt.Errorf("wrong number of values for %q in state: got %d, but need %d", prefix, count, len(etys))
	}

	vals = make([]cty.Value, len(etys))
	for i, ety := range etys {
		key := prefix + strconv.Itoa(i)
		val, err := hcl2ValueFromFlatmapValue(m, key, ety)
		if err != nil {
			return cty.DynamicVal, err
		}
		vals[i] = val
	}
	return cty.TupleVal(vals), nil
}

func hcl2ValueFromFlatmapMap(m map[string]string, prefix string, ty cty.Type) (cty.Value, error) {
	vals := make(map[string]cty.Value)
	ety := ty.ElementType()

View on GitHub (pinned to d32a084675)