hashicorp/terraform · error

invalid step with type %#v

Error message

invalid step %q with type %#v

What it means

Returned by pathFromFlatmapKeyValue when the current type at this position in the path is primitive (string, number, bool) but the flatmap key still has more segments to consume. A primitive has no further navigable structure, so any suffix (e.g. '.foo' or '.0') is invalid — the path is trying to descend into a leaf.

Solutions

  1. Inspect the full flatmap key — the suffix after the primitive attribute is spurious and should be removed.
  2. If the attribute was supposed to be an object/collection, restore or correct the schema type so descent is valid.
  3. Regenerate the diff/RequiresReplace list against the current schema so keys match the actual type structure.
  4. Validate flatmap keys against the schema before persisting them.

Example fix

// before: flatmap key 'name.first' where 'name' is cty.String
// after: flatmap key 'name' (no further descent on a primitive)
Defensive patterns

Strategy: validation

Validate before calling

func flatmapKeyRespectsPrimitiveLeaf(key string, ty cty.Type) bool {
    // Walk the type tree segment-by-segment; if a primitive is reached and key has remaining segments, fail.
    return canDescend(key, ty)
}
func canDescend(key string, ty cty.Type) bool {
    _, rest := pathSplit(key)
    if rest == "" { return true }
    if ty.IsPrimitiveType() { return false }
    // recurse into object/tuple/map/list/set as appropriate
    return true
}

Type guard

func keyIsValidForType(key string, ty cty.Type) bool {
    _, rest := pathSplit(key)
    if rest == "" { return true }
    return !ty.IsPrimitiveType()
}

Prevention

When it happens

Trigger: Calling pathFromFlatmapKeyValue (transitively from requiresReplacePath or any flatmap-key-to-cty-path helper) with a key like 'attr.leaf.deeper' where 'attr' resolves to a cty.String. The decoder walked into 'attr', found a primitive type, but still has 'leaf.deeper' left over.

Common situations: Diff or RequiresReplace keys built by string concatenation that appended extra segments beyond the leaf; schema change that turned an object-typed attribute into a primitive while old keys still descend into it; misformatted flatmap keys from custom producers.

Related errors


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

Appendix: source

Thrown at internal/configs/hcl2shim/paths.go:136

	if rest == "" {
		return path, nil
	}

	p, err := pathFromFlatmapKeyValue(rest, ty)
	if err != nil {
		return path, err
	}

	return append(path, p...), nil
}

func pathFromFlatmapKeyValue(key string, ty cty.Type) (cty.Path, error) {
	var path cty.Path
	var err error

	switch {
	case ty.IsPrimitiveType():
		err = fmt.Errorf("invalid step %q with type %#v", key, ty)
	case ty.IsObjectType():
		path, err = pathFromFlatmapKeyObject(key, ty.AttributeTypes())
	case ty.IsTupleType():
		path, err = pathFromFlatmapKeyTuple(key, ty.TupleElementTypes())
	case ty.IsMapType():
		path, err = pathFromFlatmapKeyMap(key, ty)
	case ty.IsListType():
		path, err = pathFromFlatmapKeyList(key, ty)
	case ty.IsSetType():
		path, err = pathFromFlatmapKeySet(key, ty)
	default:
		err = fmt.Errorf("unrecognized type: %s", ty.FriendlyName())
	}

	if err != nil {
		return path, err
	}

View on GitHub (pinned to d32a084675)