{"record":{"id":"0184987133e45f6e","repo":"hashicorp/terraform","slug":"s-doesn-t-support-s","errorCode":null,"errorMessage":"%s doesn't support %s","messagePattern":"(.+?) doesn't support (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/backend_plan.go","lineNumber":164,"sourceCode":"\t\tWorkspace:            w,\n\t\tAutoApply:            tfe.Bool(op.AutoApprove),\n\t\tSavePlan:             tfe.Bool(op.PlanOutPath != \"\"),\n\t}\n\n\tswitch op.PlanMode {\n\tcase plans.NormalMode:\n\t\t// okay, but we don't need to do anything special for this\n\tcase plans.RefreshOnlyMode:\n\t\trunOptions.RefreshOnly = tfe.Bool(true)\n\tcase plans.DestroyMode:\n\t\trunOptions.IsDestroy = tfe.Bool(true)\n\tdefault:\n\t\t// Shouldn't get here because we should update this for each new\n\t\t// plan mode we add, mapping it to the corresponding RunCreateOptions\n\t\t// field.\n\t\treturn nil, b.generalError(\n\t\t\t\"Invalid plan mode\",\n\t\t\tfmt.Errorf(\"%s doesn't support %s\", b.appName, op.PlanMode),\n\t\t)\n\t}\n\n\tif len(op.Targets) != 0 {\n\t\trunOptions.TargetAddrs = make([]string, 0, len(op.Targets))\n\t\tfor _, addr := range op.Targets {\n\t\t\trunOptions.TargetAddrs = append(runOptions.TargetAddrs, addr.String())\n\t\t}\n\t}\n\n\tif len(op.ActionTargets) != 0 {\n\t\tif len(op.ActionTargets) > 1 {\n\t\t\t// For now, we only support a single action from the command line.\n\t\t\t// We've future proofed the API and inputs so we can send multiple\n\t\t\t// but versions of Terraform will enforce this both here, and\n\t\t\t// on the other side.\n\t\t\t//\n\t\t\t// It shouldn't actually be possible to reach here anyway - we're","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/cloud/backend_plan.go#L146-L182","documentation":"Thrown by the Cloud backend when creating a run whose op.PlanMode value does not match any of the known cases (NormalMode, RefreshOnlyMode, DestroyMode) in the switch statement. The message reports the application name (b.appName, e.g. \"HCP Terraform\") and the unrecognized plan mode. It indicates a Terraform core/Cloud-backend version skew: a new plan mode enum exists in core but the Cloud backend was not updated to map it to a RunCreateOptions field.","triggerScenarios":"Reached only via the default branch of the op.PlanMode switch while the run is being built for a cloud workspace. Happens when a caller passes a plans.Mode value that the backend's switch has no case for (for example a brand-new mode added to the plans package before backend_plan.go gained a corresponding RunCreateOptions mapping).","commonSituations":"Mixing binaries from different Terraform versions, a custom build that adds a plan mode without patching the backend, or running an internal/experimental plan mode flag against a stock Cloud backend. End users on released versions should essentially never see this.","solutions":["Ensure the terraform binary and its internal/cloud backend are from the same release (reinstall/upgrade Terraform as a single unit).","If you are developing a new plan mode, add the missing case in backend_plan.go:151 mapping op.PlanMode to the right RunCreateOptions field, then rebuild.","Stop passing the unsupported/experimental flag (-destroy, -refresh-only are the supported CLI flags) and run a normal plan."],"exampleFix":"// before: switch with no case for a new mode\ncase plans.NewMode: // unhandled -> falls to default -> error\n// after: add an explicit case mapping the mode to a run option\ncase plans.NewMode:\n    runOptions.SomeNewField = tfe.Bool(true)","handlingStrategy":"validation","validationCode":"// Before creating a cloud run, validate the plan mode is one the backend handles.\nfunc supportedPlanMode(m plans.Mode) bool {\n    switch m {\n    case plans.NormalMode, plans.RefreshOnlyMode, plans.DestroyMode:\n        return true\n    }\n    return false\n}\nif !supportedPlanMode(op.PlanMode) {\n    return fmt.Errorf(\"plan mode %v not supported by cloud backend\", op.PlanMode)\n}","typeGuard":"// go has no TS-style guard; model plan mode as a finite typed set\ntype supportedPlanMode struct{ mode plans.Mode }\nfunc isKnownPlanMode(m plans.Mode) bool {\n    return m == plans.NormalMode || m == plans.RefreshOnlyMode || m == plans.DestroyMode\n}","tryCatchPattern":null,"preventionTips":["Keep the Terraform binary's core and cloud backend from the same release.","When adding a new plans.Mode, update the switch in backend_plan.go in the same change.","Avoid experimental/internal plan-mode flags when targeting cloud workspaces."],"tags":["terraform","cloud-backend","plan-mode","version-skew","internal"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}