{"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/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/cloud/backend_plan.go#L146-L182","documentation":"Thrown in the default branch of the switch over op.PlanMode in the cloud plan-creation path. The switch handles NormalMode, RefreshOnlyMode, and DestroyMode explicitly; any other value is rejected because there is no mapping to a tfe.RunCreateOptions field. The comment explicitly states this is a developer guard: it should be updated whenever a new plan mode is added.","triggerScenarios":"A new plans.Mode constant was added to Terraform core without a corresponding case in this switch. This is an internal Terraform bug, not a user config error — op.PlanMode is set by the CLI flags (-destroy, -refresh-only), which cannot produce an unmapped value through normal use.","commonSituations":"Running a custom/development Terraform build that added a plan mode without updating the cloud backend; a plugin or fork that injects an unexpected PlanMode value; version skew between terraform-core and the cloud backend package.","solutions":["This is almost always an internal Terraform defect — report it to the Terraform team with the op.PlanMode value from the message.","If running a fork, add a case for the new plan mode mapping it to the correct RunCreateOptions field.","Downgrade to a stable Terraform release where the cloud backend and core plan modes are in sync.","Avoid the unsupported flag combination that surfaces the new mode until the backend is updated."],"exampleFix":"// before\ncase plans.DestroyMode:\n    runOptions.IsDestroy = tfe.Bool(true)\ndefault:\n    return nil, b.generalError(\"Invalid plan mode\", ...)\n// after - add the missing mode mapping\ncase plans.DestroyMode:\n    runOptions.IsDestroy = tfe.Bool(true)\ncase plans.NewMode:\n    runOptions.NewField = tfe.Bool(true)\ndefault:\n    return nil, b.generalError(\"Invalid plan mode\", ...)","handlingStrategy":"validation","validationCode":"// Guard at the boundary before constructing the operation.\nswitch op.PlanMode {\ncase plans.NormalMode, plans.RefreshOnlyMode, plans.DestroyMode:\ndefault:\n    return fmt.Errorf(\"unsupported plan mode: %v\", op.PlanMode)\n}","typeGuard":"// Narrow plan mode to supported values.\nfunc isSupportedPlanMode(m plans.Mode) bool {\n    switch m {\n    case plans.NormalMode, plans.RefreshOnlyMode, plans.DestroyMode:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["When adding a new plans.Mode constant, update the cloud backend switch in the same change.","Use released Terraform versions; avoid forks that inject arbitrary plan modes.","Add a unit test asserting every plans.Mode has a cloud-backend case."],"tags":["terraform","plan-mode","internal-bug","api-contract","run-options"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}