opentofu/opentofu · error
ephemeral resources are not meant to be processed by this fu
Error message
ephemeral resources are not meant to be processed by this function. Are you sure that this code should be reused?
What it means
NewInstanceInfo panics when given a resource in addrs.EphemeralResourceMode. Ephemeral resources postdate the legacy provider protocols that InstanceInfo serves and never flow through legacy diff/state machinery; the panic message itself asks whether the code path should be reused for them.
Source
Thrown at internal/legacy/tofu/resource.go:130
path := make([]string, len(addr.Module))
for i, step := range addr.Module {
if step.InstanceKey != addrs.NoKey {
panic("NewInstanceInfo cannot convert module instance with key")
}
path[i] = step.Name
}
// This is a funny old meaning of "id" that is no longer current. It should
// not be used for anything users might see. Note that it does not include
// a representation of the resource mode, and so it's impossible to
// determine from an InstanceInfo alone whether it is a managed or data
// resource that is being referred to.
id := fmt.Sprintf("%s.%s", addr.Resource.Resource.Type, addr.Resource.Resource.Name)
if addr.Resource.Resource.Mode == addrs.DataResourceMode {
id = "data." + id
}
if addr.Resource.Resource.Mode == addrs.EphemeralResourceMode {
panic("ephemeral resources are not meant to be processed by this function. Are you sure that this code should be reused?")
}
if addr.Resource.Key != addrs.NoKey {
switch k := addr.Resource.Key.(type) {
case addrs.IntKey:
id = id + fmt.Sprintf(".%d", int(k))
default:
panic(fmt.Sprintf("NewInstanceInfo cannot convert resource instance with %T instance key", addr.Resource.Key))
}
}
return &InstanceInfo{
Id: id,
ModulePath: path,
Type: addr.Resource.Resource.Type,
}
}
// ResourceAddress returns the address of the resource that the receiver is describing.View on GitHub (pinned to 3561785c48)
Solutions
- Branch on addr.Resource.Resource.Mode before calling and handle ephemeral resources on modern code paths only
- Do not route ephemeral resources through legacy tofu types; use providers/addrs modern APIs instead
- If the panic fired, treat it as a design signal: this legacy function must not be reused for the new mode
Example fix
// before
info := NewInstanceInfo(instAddr)
// after
if instAddr.Resource.Resource.Mode == addrs.EphemeralResourceMode {
return nil, fmt.Errorf("ephemeral resource %s must not use legacy InstanceInfo", instAddr)
}
info := NewInstanceInfo(instAddr) Defensive patterns
Strategy: type-guard
Type guard
func isEphemeralResource(a addrs.AbsResourceInstance) bool {
return a.Resource.Resource.Mode == addrs.EphemeralResourceMode
} Prevention
- Branch on ResourceMode before calling NewInstanceInfo; ephemeral resources must stay on modern paths
- Never reuse legacy provider-facing helpers for ephemeral resources — the panic is by design
- Add a mode check to generic address-formatting utilities
When it happens
Trigger: Passing an AbsResourceInstance whose Resource.Resource.Mode is addrs.EphemeralResourceMode into NewInstanceInfo — typically generic address-formatting or logging code that handles all resource modes uniformly.
Common situations: Adding ephemeral resource support to a codebase that already calls NewInstanceInfo; refactoring shared helpers that enumerate resources of every mode; new provider features routed through legacy plumbing by mistake.
Related errors
- cannot shim %s to addrs.ResourceMode value
- ephemeral resource is not meant to be in the schema for lega
- missing root module
- invalid index value %q
- resource instance with key %#v is not supported
AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15).
Data as JSON: /api/errors/b1204a8c0a851a7c.
Report an issue: GitHub.