{"record":{"id":"3bb20a60d20caced","repo":"hashicorp/terraform","slug":"approved-using-the-ui-or-api-3bb20a","errorCode":null,"errorMessage":"approved using the UI or API","messagePattern":"approved using the UI or API","errorType":"exception","errorClass":"errRunApproved","httpStatus":null,"severity":"info","filePath":"internal/cloud/errors.go","lineNumber":19,"sourceCode":"// Copyright IBM Corp. 2014, 2026\n// SPDX-License-Identifier: BUSL-1.1\n\npackage cloud\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/hashicorp/terraform/internal/tfdiags\"\n\t\"github.com/zclconf/go-cty/cty\"\n)\n\n// String based errors\nvar (\n\terrApplyDiscarded                    = errors.New(\"Apply discarded.\")\n\terrDestroyDiscarded                  = errors.New(\"Destroy discarded.\")\n\terrRunApproved                       = errors.New(\"approved using the UI or API\")\n\terrRunDiscarded                      = errors.New(\"discarded using the UI or API\")\n\terrRunOverridden                     = errors.New(\"overridden using the UI or API\")\n\terrApplyNeedsUIConfirmation          = errors.New(\"Cannot confirm apply due to -input=false. Please handle run confirmation in the UI.\")\n\terrPolicyOverrideNeedsUIConfirmation = errors.New(\"Cannot override soft failed policy checks when -input=false. Please open the run in the UI to override.\")\n)\n\n// Diagnostic error messages\nvar (\n\tinvalidWorkspaceConfigMissingValues = tfdiags.AttributeValue(\n\t\ttfdiags.Error,\n\t\t\"Invalid workspaces configuration\",\n\t\tfmt.Sprintf(\"Missing workspace mapping strategy. Either workspace \\\"tags\\\" or \\\"name\\\" is required.\\n\\n%s\", workspaceConfigurationHelp),\n\t\tcty.Path{cty.GetAttrStep{Name: \"workspaces\"}},\n\t)\n\n\tinvalidWorkspaceConfigMisconfiguration = tfdiags.AttributeValue(\n\t\ttfdiags.Error,\n\t\t\"Invalid workspaces configuration\",","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/cloud/errors.go#L1-L37","documentation":"errRunApproved is a sentinel indicating the run was approved externally (via the HCP Terraform/TFE UI or API) while the CLI confirm() goroutine was waiting for interactive input. It is not a failure: backend_apply.go:170 explicitly excludes it from the error path (err != errRunApproved) so the apply proceeds. It exists so the CLI knows the approval happened out-of-band and should not double-submit.","triggerScenarios":"In Cloud.confirm (backend_common.go:479) for the 'yes' keyword: when the polled run's Actions.IsConfirmable becomes false and Status is not Discarded, the goroutine returns errRunApproved. The caller then skips its own Runs.Apply call.","commonSituations":"An operator confirms the run in the HCP Terraform web UI before the CLI user types 'yes'; CI approved the run via API while a developer held the prompt open.","solutions":["No action needed — the apply will continue against the already-approved run.","If unexpected, review the run's activity log in the UI to see who/what approved it."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// errRunApproved is informational: the apply proceeds, do not treat as error.\nerr := b.confirm(ctx, op, opts, run, \"yes\")\nif errors.Is(err, cloud.ErrRunApproved) || strings.Contains(err.Error(), \"approved using the UI or API\") {\n    // externally approved; continue normally\n    return nil\n}\nif err != nil {\n    return err\n}","preventionTips":["Document that out-of-band UI/API approval is valid and will not block the CLI.","Avoid double-approving: if you approve via API, cancel the CLI prompt to avoid races.","Log which path approved the run for auditability."],"tags":["cloud-backend","apply","run-lifecycle","approval","sentinel"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}