{"record":{"id":"4ae4bbdb31ff0a50","repo":"hashicorp/terraform","slug":"discarded-using-the-ui-or-api","errorCode":null,"errorMessage":"discarded using the UI or API","messagePattern":"discarded using the UI or API","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"internal/backend/remote/backend_common.go","lineNumber":29,"sourceCode":"\t\"io\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\ttfe \"github.com/hashicorp/go-tfe\"\n\n\t\"github.com/hashicorp/terraform/internal/backend/backendrun\"\n\t\"github.com/hashicorp/terraform/internal/logging\"\n\t\"github.com/hashicorp/terraform/internal/plans\"\n\t\"github.com/hashicorp/terraform/internal/terraform\"\n)\n\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)\n\nvar (\n\tbackoffMin = 1000.0\n\tbackoffMax = 3000.0\n\n\trunPollInterval = 3 * time.Second\n)\n\n// backoff will perform exponential backoff based on the iteration and\n// limited by the provided min and max (in milliseconds) durations.\nfunc backoff(min, max float64, iter int) time.Duration {\n\tbackoff := math.Pow(2, float64(iter)/5) * min\n\tif backoff > max {\n\t\tbackoff = max\n\t}\n\treturn time.Duration(backoff) * time.Millisecond","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote/backend_common.go#L11-L47","documentation":"Sentinel error raised inside the remote backend confirm() polling loop when the polled run transitions to tfe.RunDiscarded. It signals that the run was discarded via the UI or API while the CLI was waiting for local confirmation, and it is then rewritten to errApplyDiscarded or errDestroyDiscarded to abort the operation cleanly.","triggerScenarios":"During 'terraform apply' (or destroy) confirmation on a 'remote' backend, the run is discarded through the TFE/HCP UI 'Discard run' button or POST /runs/{id}/actions/discard before the operator types the keyword.","commonSituations":"A teammate cancels a stale run; CI discards a run that a developer is also reviewing at the prompt; a policy or automation discards runs in a queued state.","solutions":["Re-run the plan/apply once the conflicting discard is resolved; the discarded run cannot be resumed.","Coordinate run ownership (assign the run, comment in the UI) so only one actor confirms or discards.","If discards are automated, exclude workspaces that humans operate on interactively."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := b.confirm(ctx, op, opts, run, \"yes\"); err != nil {\n    if errors.Is(err, errRunDiscarded) || errors.Is(err, errApplyDiscarded) || errors.Is(err, errDestroyDiscarded) {\n        // run was discarded via UI/API — surface to user, no retry of this run\n        return run, err\n    }\n    return run, err\n}","preventionTips":["Coordinate who may discard runs in shared workspaces.","Surface a clear user message that the run was discarded externally and must be re-planned.","Do not auto-retry on discard — start a fresh plan instead."],"tags":["terraform","remote-backend","tfe","hcp","run-lifecycle"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}