hashicorp/terraform · error

cannot decode %s from flatmap

Error message

cannot decode %s from flatmap

What it means

Returned by hcl2ValueFromFlatmapValue (flatmap.go:176) when decoding a flatmap (the legacy string-keyed map representation of Terraform state) into a cty.Value whose type does not match any recognized kind. The switch covers primitive, object, tuple, map, list, and set; reaching the default means the cty.Type is something none of those checks recognize — typically a capsule type, a dynamically-typed value, or an internally-inconsistent type descriptor.

Source

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

func hcl2ValueFromFlatmapValue(m map[string]string, key string, ty cty.Type) (cty.Value, error) {
	var val cty.Value
	var err error
	switch {
	case ty.IsPrimitiveType():
		val, err = hcl2ValueFromFlatmapPrimitive(m, key, ty)
	case ty.IsObjectType():
		val, err = hcl2ValueFromFlatmapObject(m, key+".", ty.AttributeTypes())
	case ty.IsTupleType():
		val, err = hcl2ValueFromFlatmapTuple(m, key+".", ty.TupleElementTypes())
	case ty.IsMapType():
		val, err = hcl2ValueFromFlatmapMap(m, key+".", ty)
	case ty.IsListType():
		val, err = hcl2ValueFromFlatmapList(m, key+".", ty)
	case ty.IsSetType():
		val, err = hcl2ValueFromFlatmapSet(m, key+".", ty)
	default:
		err = fmt.Errorf("cannot decode %s from flatmap", ty.FriendlyName())
	}

	if err != nil {
		return cty.DynamicVal, err
	}
	return val, nil
}

func hcl2ValueFromFlatmapPrimitive(m map[string]string, key string, ty cty.Type) (cty.Value, error) {
	rawVal, exists := m[key]
	if !exists {
		return cty.NullVal(ty), nil
	}
	if rawVal == UnknownVariableValue {
		return cty.UnknownVal(ty), nil
	}

	var err error

View on GitHub (pinned to c9def3e214)

Solutions

  1. Print ty.FriendlyName() (it appears in the message) and confirm whether that type is supposed to be representable in a flatmap — only primitive/object/tuple/map/list/set are supported.
  2. If the type is cty.DynamicPseudoType, resolve it to a concrete type before calling HCL2ValueFromFlatmap; flatmap cannot encode fully-dynamic values.
  3. Ensure the cty.Type used for decoding matches the type that originally produced the flatmap (type mismatch between schema versions causes this).
  4. If you have a custom capsule type, decode it through a dedicated path instead of the generic flatmap shim.

Example fix

// before
val, err := hcl2shim.HCL2ValueFromFlatmap(m, key, myCapsuleType)

// after — flatmap only supports the 6 standard kinds; use a concrete type
val, err := hcl2shim.HCL2ValueFromFlatmap(m, key, cty.Map(cty.String))
Defensive patterns

Strategy: validation

Validate before calling

// Only the 6 standard cty kinds are decodable from a flatmap
func isFlatmapDecodable(ty cty.Type) bool {
    return ty.IsPrimitiveType() || ty.IsObjectType() || ty.IsTupleType() ||
        ty.IsMapType() || ty.IsListType() || ty.IsSetType()
}
// Resolve dynamic types and reject unsupported kinds BEFORE decoding:
if !isFlatmapDecodable(ty) {
    return cty.DynamicVal, fmt.Errorf("flatmap cannot decode type %s", ty.FriendlyName())
}

Type guard

func isFlatmapDecodable(ty cty.Type) bool {
    return ty.IsPrimitiveType() || ty.IsObjectType() || ty.IsTupleType() ||
        ty.IsMapType() || ty.IsListType() || ty.IsSetType()
}

Try / catch

val, err := hcl2shim.HCL2ValueFromFlatmap(m, key, ty)
if err != nil {
    // fall back to a null of the type rather than propagating a decode failure
    log.Printf("flatmap decode failed for %s: %v", ty.FriendlyName(), err)
    return cty.NullVal(ty), nil
}

Prevention

When it happens

Trigger: Calling HCL2ValueFromFlatmap with a cty.Type that is not one of the six handled kinds (e.g. a cty.Capsule type, or a type produced by cty.DynamicPseudoType that was not resolved before decoding). Also reachable when a custom/extended cty type leaks into the flatmap round-trip path.

Common situations: State migration or import code that passes a schema type containing dynamic pseudo-types without first resolving them. Provider schemas that declare attributes with unsupported underlying types. Hand-edited or third-party-tampered state files paired with a schema that doesn't match.

Related errors


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