hashicorp/terraform · error
Failed to marshal index step key %#v: %s
Error message
Failed to marshal index step key %#v: %s
What it means
In encodePath, ctyjson.Marshal(s.Key, s.Key.Type()) for a cty.IndexStep key failed. The index key is a cty.Value; this error means its type cannot be serialized to JSON, so the path cannot be encoded losslessly.
Source
Thrown at internal/command/jsonplan/plan.go:1072
for _, path := range pathList {
jsonPath, err := encodePath(path)
if err != nil {
return nil, err
}
jsonPaths = append(jsonPaths, jsonPath)
}
return json.Marshal(jsonPaths)
}
func encodePath(path cty.Path) (json.RawMessage, error) {
steps := make([]json.RawMessage, 0, len(path))
for _, step := range path {
switch s := step.(type) {
case cty.IndexStep:
key, err := ctyjson.Marshal(s.Key, s.Key.Type())
if err != nil {
return nil, fmt.Errorf("Failed to marshal index step key %#v: %s", s.Key, err)
}
steps = append(steps, key)
case cty.GetAttrStep:
name, err := json.Marshal(s.Name)
if err != nil {
return nil, fmt.Errorf("Failed to marshal get attr step name %#v: %s", s.Name, err)
}
steps = append(steps, name)
default:
return nil, fmt.Errorf("Unsupported path step %#v (%t)", step, step)
}
}
return json.Marshal(steps)
}
View on GitHub (pinned to c9def3e214)
Solutions
- Inspect the key shown via %#v to learn its type.
- Avoid relying on that attribute path in replace detection if possible.
- Report as a renderer bug if it occurs on a common/primitive key type.
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate that every IndexStep key in recorded paths is JSON-serializable
// before marshaling, so failures surface with context.
for _, ra := range plan.RelevantAttributes {
for _, step := range ra.Attr {
if idx, ok := step.(cty.IndexStep); ok {
if _, err := ctyjson.Marshal(idx.Key, idx.Key.Type()); err != nil {
return fmt.Errorf("unserializable index key %#v in relevant attribute path: %w", idx.Key, err)
}
}
}
} Type guard
func serializablePathStep(step cty.PathStep) error {
switch s := step.(type) {
case cty.IndexStep:
_, err := ctyjson.Marshal(s.Key, s.Key.Type())
return err
case cty.GetAttrStep:
return nil // string name; validated separately
default:
return fmt.Errorf("unsupported step %T", step)
}
} Try / catch
out, err := jsonplan.Marshal(config, plan, sf, schemas)
if err != nil && strings.Contains(err.Error(), "marshal index step key") {
// a path index key is not JSON-serializable; capture the %#v value for triage
}
return err Prevention
- Avoid configurations that produce relevant-attribute paths keyed by complex object types.
- When logging path-encoding errors, include the key's type (%T) not just its value.
- Report occurrences on primitive key types as renderer bugs.
When it happens
Trigger: A relevant-attribute or replace path includes an IndexStep whose key is of a non-JSON-serializable type (e.g. a complex object used as a set element key). Reached via encodePaths/encodePath from relevant attributes (607) or replace_paths encoding.
Common situations: Paths into set-typed attributes where elements are keyed by a structured type; an internal type-handling gap for an unusual attribute type; rarely, a corrupted path.
Related errors
- error marshaling relevant attributes for external changes: %
- Failed to marshal get attr step name %#v: %s
- unrecognized type: %s
- error in marshalPlanVariables: %s
- error in marshalPlannedValues: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/02ac1c1de9dcf8e1.
Report an issue: GitHub.