hashicorp/terraform · critical
found unrecognized resource mode:
Error message
found unrecognized resource mode:
What it means
A panic in `Plan.getSchema` (internal/command/jsonformat/plan.go:50) triggered when a resource change's `Mode` field matches neither `ManagedResourceMode` nor `DataResourceMode`. The default case of the switch concatenates the unknown mode into the panic message. It is an internal invariant: every resource change in a well-formed plan JSON must be either managed or data. Hitting it means the plan JSON is malformed or produced by an incompatible Terraform version.
Source
Thrown at internal/command/jsonformat/plan.go:50
OutputChanges map[string]jsonplan.Change `json:"output_changes,omitempty"`
ResourceChanges []jsonplan.ResourceChange `json:"resource_changes,omitempty"`
ResourceDrift []jsonplan.ResourceChange `json:"resource_drift,omitempty"`
RelevantAttributes []jsonplan.ResourceAttr `json:"relevant_attributes,omitempty"`
DeferredChanges []jsonplan.DeferredResourceChange `json:"deferred_changes,omitempty"`
ActionInvocations []jsonplan.ActionInvocation `json:"action_invocations,omitempty"`
ProviderFormatVersion string `json:"provider_format_version"`
ProviderSchemas map[string]*jsonprovider.Provider `json:"provider_schemas,omitempty"`
}
func (plan Plan) getSchema(change jsonplan.ResourceChange) *jsonprovider.Schema {
switch change.Mode {
case jsonstate.ManagedResourceMode:
return plan.ProviderSchemas[change.ProviderName].ResourceSchemas[change.Type]
case jsonstate.DataResourceMode:
return plan.ProviderSchemas[change.ProviderName].DataSourceSchemas[change.Type]
default:
panic("found unrecognized resource mode: " + change.Mode)
}
}
func (plan Plan) getActionSchema(ai jsonplan.ActionInvocation) *jsonprovider.ActionSchema {
return plan.ProviderSchemas[ai.ProviderName].ActionSchemas[ai.Type]
}
func (plan Plan) renderHuman(renderer Renderer, mode plans.Mode, opts ...plans.Quality) {
checkOpts := func(target plans.Quality) bool {
return slices.Contains(opts, target)
}
diffs := precomputeDiffs(plan, mode)
haveRefreshChanges := renderHumanDiffDrift(renderer, diffs, mode)
willPrintResourceChanges := false
counts := make(map[plans.Action]int)
importingCount := 0View on GitHub (pinned to c9def3e214)
Solutions
- Regenerate the plan with the same Terraform version used to render or apply it, and never downgrade across a plan.
- If using `terraform show -json` output programmatically, validate `resource_changes[].mode` is in {managed, data} before processing.
- Report as a Terraform bug if reproduced with unmodified stock Terraform and a freshly generated plan.
- Avoid hand-editing or rewriting plan JSON files; treat plans as opaque artifacts.
Example fix
// before: consuming plan JSON without validation
for _, rc := range planJSON["resource_changes"].([]interface{}) {
schema := getSchema(rc) // panics on unknown mode
}
// after: validate mode before dispatching
for _, rc := range planJSON["resource_changes"].([]interface{}) {
mode := rc.(map[string]interface{})["mode"].(string)
if mode != "managed" && mode != "data" {
return fmt.Errorf("unsupported resource mode %q; regenerate plan with current terraform", mode)
}
schema := getSchema(rc)
} Defensive patterns
Strategy: validation
Validate before calling
// Go: validate plan JSON modes before passing to jsonformat rendering
func validateResourceModes(planJSON []byte) error {
var p struct {
RC []struct{ Mode string `json:"mode"` } `json:"resource_changes"`
}
if err := json.Unmarshal(planJSON, &p); err != nil {
return err
}
for _, rc := range p.RC {
if rc.Mode != "managed" && rc.Mode != "data" {
return fmt.Errorf("unrecognized resource mode %q; regenerate plan with current terraform", rc.Mode)
}
}
return nil
} Try / catch
// Go: recover from the jsonformat panic and surface a controlled error
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("plan rendering failed (likely version skew): %v", r)
}
}()
renderer.Render(plan) Prevention
- Never apply or render a plan with a different Terraform version than produced it.
- Treat plan files as opaque; do not hand-edit resource mode fields.
- If consuming `terraform show -json` output, validate mode against {managed, data} first.
- Pin Terraform versions across CI and local environments.
When it happens
Trigger: Rendering or applying a JSON plan (`terraform show -json`, `terraform apply tfplan`) where a `resource_changes[].mode` entry holds an unrecognized value (not 'managed' or 'data'). Typically from a hand-edited plan file, a plan produced by a newer Terraform that introduced a new resource mode, or third-party tooling that wrote non-standard JSON.
Common situations: Version skew: generating a plan with Terraform 1.x and rendering/applying it with an older binary; corrupted plan files; tooling that round-trips plan JSON incorrectly; experimental forks of Terraform.
Related errors
- found unrecognized resource mode:
- unrecognized action slice:
- resource %s has an unsupported mode %s
- resource %s has an unsupported mode %s
- Workspace data missing from plan file. Current workspace is
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/998f8a553f061d9f.
Report an issue: GitHub.