{"record":{"id":"5d12331ead96456a","repo":"opentofu/opentofu","slug":"can-t-show-a-saved-cloud-plan-unless-the-current-r","errorCode":null,"errorMessage":"can't show a saved cloud plan unless the current root module is connected to Terraform Cloud","messagePattern":"can't show a saved cloud plan unless the current root module is connected to Terraform Cloud","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/show.go","lineNumber":402,"sourceCode":"\t\tplan, stateFile, config, err = getDataFromPlanfileReader(ctx, lp, rootCall)\n\t} else if cp, ok := pf.Cloud(); ok {\n\t\tredacted := c.viewType != arguments.ViewJSON\n\t\tjsonPlan, err = c.getDataFromCloudPlan(ctx, cp, redacted, enc)\n\t}\n\n\treturn plan, jsonPlan, stateFile, config, err\n}\n\nfunc (c *ShowCommand) getDataFromCloudPlan(ctx context.Context, plan *cloudplan.SavedPlanBookmark, redacted bool, enc encryption.Encryption) (*cloudplan.RemotePlanJSON, error) {\n\t// Set up the backend\n\tb, backendDiags := c.Backend(ctx, nil, enc.State())\n\tif backendDiags.HasErrors() {\n\t\treturn nil, errUnusable(backendDiags.Err(), \"cloud plan\")\n\t}\n\t// Cloud plans only work if we're cloud.\n\tcl, ok := b.(*cloud.Cloud)\n\tif !ok {\n\t\treturn nil, errUnusable(fmt.Errorf(\"can't show a saved cloud plan unless the current root module is connected to Terraform Cloud\"), \"cloud plan\")\n\t}\n\n\tresult, err := cl.ShowPlanForRun(context.Background(), plan.RunID, plan.Hostname, redacted)\n\tif err != nil {\n\t\terr = errUnusable(err, \"cloud plan\")\n\t}\n\treturn result, err\n}\n\n// maybeGetSchemas is a thin wrapper around [Meta.MaybeGetSchemas] that\n// takes a [*statefile.File] instead of a [*states.State] and tolerates\n// the state file being nil, since that's more convenient for the\n// \"tofu show\" methods that may or may not have a state file to use.\nfunc (c *ShowCommand) maybeGetSchemas(ctx context.Context, stateFile *statefile.File, config *configs.Config) (*tofu.Schemas, tfdiags.Diagnostics) {\n\tctx, span := tracing.Tracer().Start(ctx, \"Get Schemas\")\n\tdefer span.End()\n\n\tif stateFile == nil {","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/command/show.go#L384-L420","documentation":"getDataFromCloudPlan runs when the file passed to tofu show is a saved cloud plan bookmark (cloudplan.SavedPlanBookmark, containing a run ID and hostname) rather than a local plan. It requires the backend resolved from the current configuration to be *cloud.Cloud, i.e. the root module must be connected to Terraform Cloud via the cloud block. If the current configuration resolves to any other backend, the plan JSON cannot be fetched and this error is returned.","triggerScenarios":"Running tofu show <plan-file> where the file was written by a run driven by the cloud backend, while the current root module has no cloud block or uses a backend block; commenting out the cloud block between saving and showing the plan; running show from a different directory whose backend differs.","commonSituations":"Viewing a cloud-run plan artifact on a laptop checkout that uses a local or S3 backend; mid-migration off Terraform Cloud; plan files shared between machines or branches with different backend configs.","solutions":["Restore the cloud block configuration that produced the plan and run tofu init, then retry tofu show <plan>","View the plan in the Terraform Cloud UI for the run ID embedded in the bookmark instead of locally","Regenerate the plan locally with the current backend if cloud access is not intended","Confirm you are in the same root module directory that created the plan file"],"exampleFix":"# before\n# plan saved under cloud backend, cloud block now commented out\ntofu show tfplan   # can't show a saved cloud plan\n\n# after\nterraform {\n  cloud {\n    organization = \"my-org\"\n    workspaces { name = \"ws\" }\n  }\n}\n# then: tofu init && tofu show tfplan","handlingStrategy":"validation","validationCode":"raw, err := os.ReadFile(planPath)\nif err != nil {\n\treturn err\n}\nif bytes.Contains(raw, []byte(\"run_id\")) {\n\t// saved cloud plan bookmark: tofu show needs the cloud{} backend active,\n\t// otherwise it fails with the 'connected to Terraform Cloud' error\n\tif !cloudBackendActive() {\n\t\treturn errors.New(\"plan is a cloud bookmark; restore the cloud block or view it in TFC\")\n\t}\n}","typeGuard":"func isCloudPlanBookmark(raw []byte) bool {\n\tvar probe struct {\n\t\tCloudPlan *struct {\n\t\t\tRunID    string `json:\"run_id\"`\n\t\t\tHostname string `json:\"hostname\"`\n\t\t} `json:\"cloud_plan\"`\n\t}\n\treturn json.Unmarshal(raw, &probe) == nil && probe.CloudPlan != nil\n}","tryCatchPattern":"result, err := getDataFromCloudPlan(ctx, bookmark, redacted, enc)\nif err != nil {\n\tif strings.Contains(err.Error(), \"connected to Terraform Cloud\") {\n\t\t// backend mismatch: point the user at the TFC run instead of retrying\n\t\treturn fmt.Errorf(\"open the plan at https://%s/app/.../runs/%s\", bookmark.Hostname, bookmark.RunID)\n\t}\n\treturn err\n}","preventionTips":["Keep the cloud block in the configuration until saved plan files have been consumed","Prefer tofu show -json <local-plan> artifacts produced by the same backend configuration","Document which backend produced each shared plan file"],"tags":["go","opentofu","cloud","plan","backend"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}