hashicorp/terraform · error

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

Error message

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

What it means

Returned by hcl2ValueFromFlatmapTuple (flatmap.go:240) when the integer length stored in the flatmap count key does not equal len(etys) — the number of element types declared in the tuple schema. Tuples have a fixed, positionally-typed shape, so any mismatch between the stored element count and the schema's declared tuple arity is a structural inconsistency.

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 c9def3e214)

Solutions

  1. Compare the schema's tuple arity against the state's count value (both shown in the message); bring them into agreement.
  2. If you intentionally changed the tuple schema, write a state migration to add/remove element entries and update the count together.
  3. Pin the provider version whose schema matches the state, apply once to normalize, then upgrade.
  4. If unsure which is correct, re-import the resource to regenerate a consistent flatmap.

Example fix

// before — schema: cty.Tuple([]cty.Type{cty.String, cty.Number})
// state:  "config.#": "3"  (arity mismatch)

// after — align state element count with tuple arity
"config.#": "2"
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the flatmap tuple count matches the schema's declared arity
func tupleCountMatches(m map[string]string, prefix string, etys []cty.Type) error {
    s, ok := m[prefix+"#"]
    if !ok {
        return nil
    }
    n, err := strconv.Atoi(s)
    if err != nil {
        return fmt.Errorf("count for %s is not an integer", prefix)
    }
    if n != len(etys) {
        return fmt.Errorf("count %d != tuple arity %d for %s", n, len(etys), prefix)
    }
    return nil
}

Prevention

When it happens

Trigger: Decoding a tuple-typed attribute where the flatmap '<prefix>#' count is an integer but differs from the number of TupleElementTypes in the schema's cty.Tuple type. For example schema declares tuple([string, number]) (arity 2) but state count says 3.

Common situations: A provider schema tuple's element types were changed (added/removed a positional element) without migrating existing state. State from a different provider version. Manual edits that changed the count key without adding/removing corresponding element keys.

Related errors


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