opentofu/opentofu · error
invalid opManagedPerformDepose currentObj: %w
Error message
invalid opManagedPerformDepose currentObj: %w
What it means
While decoding an opManagedPerformDepose node, operand 0 (currentObj) did not reference a result of type *exec.ResourceInstanceObject — typically a Builder.ResourceInstancePrior result describing the object about to be deposed. The wrapped 'refers to X, but need Y' text comes from unmarshalGetPrevResultOf; nil slots coerce to NilResultRef without error, so this is a definite wrong-type reference in the serialized graph. Unmodified Marshal output cannot trigger it.
Source
Thrown at internal/engine/internal/execgraph/graph_unmarshal.go:254
}
deletePlan, err := unmarshalGetPrevResultOf[*exec.ManagedResourceObjectFinalPlan](prevResults, rawOperands[0])
if err != nil {
return nil, fmt.Errorf("invalid opManagedPrepareDepose deletePlan: %w", err)
}
deposedKey, err := unmarshalGetPrevResultOf[addrs.DeposedKey](prevResults, rawOperands[1])
if err != nil {
return nil, fmt.Errorf("invalid opManagedPrepareDepose deposedKey: %w", err)
}
return builder.ManagedPrepareDepose(deletePlan, deposedKey), nil
}
func unmarshalOpManagedPerformDepose(rawOperands []uint64, prevResults []AnyResultRef, builder *Builder) (AnyResultRef, error) {
if len(rawOperands) != 3 {
return nil, fmt.Errorf("wrong number of operands (%d) for opManagedPerformDepose", len(rawOperands))
}
currentObj, err := unmarshalGetPrevResultOf[*exec.ResourceInstanceObject](prevResults, rawOperands[0])
if err != nil {
return nil, fmt.Errorf("invalid opManagedPerformDepose currentObj: %w", err)
}
finalDeletePlan, err := unmarshalGetPrevResultOf[*exec.ManagedResourceObjectFinalPlan](prevResults, rawOperands[1])
if err != nil {
return nil, fmt.Errorf("invalid opManagedPerformDepose finalDeletePlan: %w", err)
}
waitFor, err := unmarshalGetPrevResultWaiter(prevResults, rawOperands[2])
if err != nil {
return nil, fmt.Errorf("invalid opManagedPerformDepose waitFor: %w", err)
}
return builder.ManagedPerformDepose(currentObj, finalDeletePlan, waitFor), nil
}
func unmarshalOpManagedDeposedMeta(rawOperands []uint64, prevResults []AnyResultRef, builder *Builder) (AnyResultRef, error) {
if len(rawOperands) != 3 {
return nil, fmt.Errorf("wrong number of operands (%d) for unmarshalOpManagedDeposedMeta", len(rawOperands))
}
instAddr, err := unmarshalGetPrevResultOf[addrs.AbsResourceInstance](prevResults, rawOperands[0])
if err != nil {View on GitHub (pinned to 3561785c48)
Solutions
- Regenerate the plan with the same binary and re-apply
- Re-create or checksum-verify the plan artifact
- In programmatic graphs, pass the Builder.ResourceInstancePrior result for the instance being deposed as ManagedPerformDepose's first argument
- Report an OpenTofu bug with the plan if the same version round-tripped it
Example fix
# before deposeRef := builder.ManagedPerformDepose(addrRef, deletePlanRef, waiterRef) // currentObj slot holds an address ref # after currentObjRef := builder.ResourceInstancePrior(addrRef) // ResultRef[*exec.ResourceInstanceObject] deposeRef := builder.ManagedPerformDepose(currentObjRef, deletePlanRef, waiterRef)
Defensive patterns
Strategy: try-catch
Try / catch
graph, err := execgraph.UnmarshalGraph(plan.ExecutionGraph)
if err != nil {
return nil, fmt.Errorf("invalid execution graph in plan (opManagedPerformDepose currentObj operand): %w", err)
} Prevention
- Source currentObj from Builder.ResourceInstancePrior or another object-typed result
- Prefer compile-time-typed Builder calls over manual AnyResultRef wiring
- Apply plans only from the binary that wrote them
When it happens
Trigger: UnmarshalGraph where opManagedPerformDepose's operands[0] points at an element of another type, e.g. an address constant or a final-plan result, due to operand-position shifts or corrupted bytes.
Common situations: Cross-version plan files exercising create-before-destroy; corrupted or re-serialized artifacts; forks rewiring the depose subgraph; hand-built ExecutionGraph bytes.
Related errors
- invalid opManagedPrepareDepose deletePlan: %w
- invalid opManagedPrepareDepose deposedKey: %w
- invalid opManagedPerformDepose finalDeletePlan: %w
- invalid opManagedApplyChanges fallbackObj: %w
- wrong number of operands (%d) for opManagedPrepareDepose
AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15).
Data as JSON: /api/errors/a670b944fe6c4917.
Report an issue: GitHub.