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
- Confirm the schema's tuple element type count matches the count sentinel in state; if the schema legitimately changed arity, write a state upgrader.
- Restore state from a backup written under the matching schema version.
- Pin the provider version so schema and state evolve together, then upgrade deliberately.
- 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
- Keep provider versions aligned with state; widen tuple arity only via a state upgrader.
- Prefer cty.List over cty.Tuple when the collection is conceptually variable-length.
- Add a schema-state compatibility test that decodes representative state against each schema change.
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
- attribute not found
- index out of range in %#v
- invalid count value for
- cannot decode from flatmap
- invalid step with type %#v
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)