{"record":{"id":"9a367bc59efa5047","repo":"opentofu/opentofu","slug":"the-cloud-backend-does-not-support-the-q-operat","errorCode":null,"errorMessage":"\n\nThe cloud backend does not support the %q operation.","messagePattern":"\n\nThe cloud backend does not support the %q operation\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/backend.go","lineNumber":830,"sourceCode":"\tvar f func(context.Context, context.Context, context.Context, *backend.Operation, *tfe.Workspace) (*tfe.Run, error)\n\tswitch op.Type {\n\tcase backend.OperationTypePlan:\n\t\tf = b.opPlan\n\tcase backend.OperationTypeApply:\n\t\tf = b.opApply\n\tcase backend.OperationTypeRefresh:\n\t\t// The `tofu refresh` command has been deprecated in favor of `tofu apply -refresh-state`.\n\t\t// Rather than respond with an error telling the user to run the other command we can just run\n\t\t// that command instead. We will tell the user what we are doing, and then do it.\n\t\tif b.View != nil {\n\t\t\tb.View.PreRefresh()\n\t\t}\n\t\top.PlanMode = plans.RefreshOnlyMode\n\t\top.PlanRefresh = true\n\t\top.AutoApprove = true\n\t\tf = b.opApply\n\tdefault:\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"\\n\\nThe cloud backend does not support the %q operation.\", op.Type)\n\t}\n\n\t// Lock\n\tb.opLock.Lock()\n\n\t// Build our running operation\n\t// the runningCtx is only used to block until the operation returns.\n\trunningCtx, done := context.WithCancel(context.Background())\n\trunningOp := &backend.RunningOperation{\n\t\tContext:   runningCtx,\n\t\tPlanEmpty: true,\n\t}\n\n\t// stopCtx wraps the context passed in, and is used to signal a graceful Stop.\n\tstopCtx, stop := context.WithCancel(ctx)\n\trunningOp.Stop = stop\n","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/cloud/backend.go#L812-L848","documentation":"Returned by Cloud.Operation (internal/cloud/backend.go:830) when the requested backend operation type is anything other than plan, apply, or refresh (refresh is rewritten to apply -refresh-state). The cloud backend simply has no implementation for other operation types, so it refuses with the %q-quoted op.Type.","triggerScenarios":"Calling backend Operation with op.Type set to console, validate, or any value the cloud package has no case for; programmatically reusing a local-backend operation struct against the cloud backend.","commonSituations":"Embedding code (tests, tools) that iterates all backend.OperationTypes; attempting `tofu console`/`tofu validate` semantics through the cloud backend instead of the local backend; drift between backend.OperationType constants and the cloud package's switch after a new type is added upstream.","solutions":["Route the operation to the local backend (b.local.Operation) for non plan/apply/refresh types, as the cloud backend itself does for local-execution workspaces.","If writing a tool, whitelist op.Type to backend.OperationTypePlan/Apply before handing the operation to the cloud backend.","For refresh, keep using OperationTypeRefresh - it is supported via the apply/refresh-only rewrite, no code change needed."],"exampleFix":"// before\nrunningOp, err := cloudBackend.Operation(ctx, op) // op.Type = OperationTypeValidate\n\n// after\nif op.Type != backend.OperationTypePlan && op.Type != backend.OperationTypeApply && op.Type != backend.OperationTypeRefresh {\n    return localBackend.Operation(ctx, op)\n}\nrunningOp, err := cloudBackend.Operation(ctx, op)","handlingStrategy":"validation","validationCode":"// Only hand supported op types to the cloud backend\nsupported := map[backend.OperationType]bool{\n    backend.OperationTypePlan: true,\n    backend.OperationTypeApply: true,\n    backend.OperationTypeRefresh: true,\n}\nif !supported[op.Type] {\n    return local.Operation(ctx, op) // or reject earlier\n}","typeGuard":"func cloudBackendSupports(t backend.OperationType) bool {\n    switch t {\n    case backend.OperationTypePlan, backend.OperationTypeApply, backend.OperationTypeRefresh:\n        return true\n    }\n    return false\n}","tryCatchPattern":"if _, err := cloud.Operation(ctx, op); err != nil {\n    if strings.Contains(err.Error(), \"does not support the\") {\n        // programming error on caller side: fix dispatch, do not retry\n    }\n}","preventionTips":["Centralize backend dispatch in one helper that whitelists op types.","When adding new backend.OperationType values, grep internal/cloud for the switch and update both.","Use the local backend for console/validate style flows."],"tags":["cloud-backend","operation","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}