hashicorp/terraform · error
can't show a saved cloud plan unless the current root…
Error message
can't show a saved cloud plan unless the current root module is connected to %s
What it means
Returned by `ShowCommand.getDataFromCloudPlan` when the configured backend for the current working directory is not the HCP Terraform / TFE `cloud` backend, but the plan bookmark being shown is a remote cloud plan. The current backend type is asserted via `b.(*cloud.Cloud)`; on failure this error is produced. NOTE: there is a latent bug in the source — on the `!ok` branch `cl` is nil, so `cl.AppName()` will panic before this error is ever returned in builds without nil-guarding; treat any actual sighting as a potential panic.
Solutions
- Run `terraform show` in the directory whose backend is the same `cloud` block that produced the plan.
- Ensure `terraform init` has configured the cloud backend (the `cloud` block is present and logged in).
- If you only have the plan JSON, use `terraform show -json <file>` on the exported JSON instead of a cloud bookmark.
Defensive patterns
Strategy: validation
Validate before calling
// Validate the backend is cloud before attempting to read a cloud plan:
b, diags := c.backend(".", c.viewType)
if diags.HasErrors() { return nil, errUnusable(diags.Err(), "cloud plan") }
cl, ok := b.(*cloud.Cloud)
if !ok {
name := "HCP Terraform"
return nil, errUnusable(errors.New("current backend is not a cloud backend"), "cloud plan")
} Type guard
// isCloudBackend narrows the backend to the cloud type without dereferencing nil.
func isCloudBackend(b backend.Backend) (*cloud.Cloud, bool) {
cl, ok := b.(*cloud.Cloud)
if !ok || cl == nil {
return nil, false
}
return cl, true
} Prevention
- Run `terraform show` for cloud plans only in directories whose backend is the same `cloud` block.
- Prefer exporting plan JSON (`-json`) for cross-environment inspection.
- Mind the latent nil-deref: never call methods on a failed type-assertion result.
When it happens
Trigger: `terraform show <saved-plan>` is invoked with a `SavedPlanBookmark` produced by a cloud run, but the working directory's backend resolves to local, s3, remote, etc. — anything other than `*cloud.Cloud`.
Common situations: Checking out a saved cloud plan locally after switching the `backend`/`cloud` block to a local backend; running `terraform show` on a plan JSON copied from a cloud run in a directory that is not cloud-connected; CI that fetched a plan bookmark into a non-cloud workspace.
Related errors
- Can't ask approval for state migration when interactive…
- error: using a saved cloud plan when executing Terraform…
- failed to initialize cloudplugin cache directory
- unknown view type
- unknown view type
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/d3c076886b8853fd.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/show.go:307
} else if cp, ok := pf.Cloud(); ok {
redacted := c.viewType != arguments.ViewJSON
jsonPlan, err = c.getDataFromCloudPlan(cp, redacted)
}
return plan, jsonPlan, stateFile, config, err
}
func (c *ShowCommand) getDataFromCloudPlan(plan *cloudplan.SavedPlanBookmark, redacted bool) (*cloudplan.RemotePlanJSON, error) {
// Set up the backend
b, diags := c.backend(".", c.viewType)
if diags.HasErrors() {
return nil, errUnusable(diags.Err(), "cloud plan")
}
// Cloud plans only work if we're cloud.
cl, ok := b.(*cloud.Cloud)
if !ok {
errMessage := fmt.Sprintf("can't show a saved cloud plan unless the current root module is connected to %s", cl.AppName())
return nil, errUnusable(errors.New(errMessage), "cloud plan")
}
result, err := cl.ShowPlanForRun(context.Background(), plan.RunID, plan.Hostname, redacted)
if err != nil {
err = errUnusable(err, "cloud plan")
}
return result, err
}
// getDataFromPlanfileReader returns a plan, statefile, and config, extracted from a local plan file.
func getDataFromPlanfileReader(planReader *planfile.Reader, allowLanguageExperiments bool, variableValues map[string]arguments.UnparsedVariableValue) (*plans.Plan, *statefile.File, *configs.Config, error) {
// Get plan
plan, err := planReader.ReadPlan()
if err != nil {
return nil, nil, nil, err
}
// Get statefileView on GitHub (pinned to d32a084675)