hashicorp/terraform · info
approved using the UI or API
Error message
approved using the UI or API
What it means
Sentinel error used by the legacy 'remote' backend during the interactive confirmation loop. While the CLI blocks waiting for the operator to type the confirmation keyword, a goroutine concurrently polls the TFE/HCP run; when the run's Actions.IsConfirmable flips false and the status is not RunDiscarded, the run was approved out-of-band (web UI or API), so this sentinel tells the caller to skip issuing its own Runs.Apply since the run is already approved.
Source
Thrown at internal/backend/remote/backend_common.go:28
"fmt"
"io"
"math"
"strconv"
"strings"
"time"
tfe "github.com/hashicorp/go-tfe"
"github.com/hashicorp/terraform/internal/backend/backendrun"
"github.com/hashicorp/terraform/internal/logging"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/terraform"
)
var (
errApplyDiscarded = errors.New("Apply discarded.")
errDestroyDiscarded = errors.New("Destroy discarded.")
errRunApproved = errors.New("approved using the UI or API")
errRunDiscarded = errors.New("discarded using the UI or API")
errRunOverridden = errors.New("overridden using the UI or API")
)
var (
backoffMin = 1000.0
backoffMax = 3000.0
runPollInterval = 3 * time.Second
)
// backoff will perform exponential backoff based on the iteration and
// limited by the provided min and max (in milliseconds) durations.
func backoff(min, max float64, iter int) time.Duration {
backoff := math.Pow(2, float64(iter)/5) * min
if backoff > max {
backoff = max
}View on GitHub (pinned to c9def3e214)
Solutions
- No fix needed — this is informational; the CLI simply proceeds to wait for the apply to complete and reports it was approved elsewhere.
- If out-of-band approval is unexpected, audit workspace members and review the run activity log in the TFE/HCP UI.
- Enable Auto-Apply on the workspace to remove the interactive confirmation step and avoid the race entirely.
Defensive patterns
Strategy: try-catch
Try / catch
// When consuming the remote backend's confirm result, distinguish the
// 'approved elsewhere' sentinel from real failures:
if err := b.confirm(ctx, op, opts, run, "yes"); err != nil {
if errors.Is(err, errRunApproved) {
// already approved via UI/API — proceed to waitForRun, do not call Apply
return b.waitForRun(ctx, cancelCtx, op, "apply", run, w)
}
return run, err // genuine error
} Prevention
- Enable Auto-Apply on workspaces to avoid interactive confirmation races.
- Communicate run ownership so only one actor approves a given run.
- Treat errRunApproved/errors.Is as control flow, never as a hard failure.
When it happens
Trigger: Running 'terraform apply' against a 'remote' backend workspace with auto_apply disabled; while the CLI shows the 'yes' prompt, another user or automation approves the same run via the TFE/HCP UI or POST /runs/{id}/actions/apply before the operator confirms locally.
Common situations: Multiple engineers watching one workspace; a CI pipeline and a human both acting on the same run; an automated approval webhook firing while someone sits at the prompt.
Related errors
- discarded using the UI or API
- overridden using the UI or API
- operation timed out
- your version of Terraform Enterprise does not support key-va
- operation timed out
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/01b22dcc6e05a298.
Report an issue: GitHub.