hashicorp/terraform · error

Error asking %s: %v

Error message

Error asking %s: %v

What it means

In confirm(), op.UIIn.Input() returned an error that is neither context.Canceled nor caused by stopCtx being canceled. It means the interactive input read (the prompt for 'yes'/'override') failed for a genuine reason — EOF, broken pipe, or the UI implementation errored — not because the operation was cleanly canceled.

Source

Thrown at internal/backend/remote/backend_common.go:557

					if err == errRunDiscarded {
						err = errApplyDiscarded
						if op.PlanMode == plans.DestroyMode {
							err = errDestroyDiscarded
						}
					}

					result <- err
					return
				}
			}
		}
	}()

	result <- func() error {
		v, err := op.UIIn.Input(doneCtx, opts)
		if err != nil && err != context.Canceled && stopCtx.Err() != context.Canceled {
			return fmt.Errorf("Error asking %s: %v", opts.Id, err)
		}

		// We return the error of our parent channel as we don't
		// care about the error of the doneCtx which is only used
		// within this function. So if the doneCtx was canceled
		// because stopCtx was canceled, this will properly return
		// a context.Canceled error and otherwise it returns nil.
		if doneCtx.Err() == context.Canceled || stopCtx.Err() == context.Canceled {
			return stopCtx.Err()
		}

		// Make sure we cancel the context here so the loop that
		// checks for external changes to the run is ended before
		// we start to make changes ourselves.
		cancel()

		if v != keyword {
			// Retrieve the run again to get its current status.

View on GitHub (pinned to c9def3e214)

Solutions

  1. Run in a real terminal, or supply `-auto-approve` / pipe the expected keyword so no interactive read is needed.
  2. For CI, avoid interactive prompts entirely by pre-approving or using the auto-approve flag.
  3. If embedding, ensure the UIIn implementation returns context.Canceled on shutdown rather than a raw error.

Example fix

// before - interactive prompt fails in headless CI
$ terraform apply   # prompts for 'yes', stdin is closed -> EOF

// after - auto-approve or feed input
$ terraform apply -auto-approve
# or
$ echo yes | terraform apply
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure an interactive UI is available before prompting.
func canPrompt(op *backendrun.Operation) bool {
    return op.UIIn != nil && op.UIOut != nil
}

Type guard

func isContextCanceled(err error) bool {
    return errors.Is(err, context.Canceled)
}

Try / catch

v, err := op.UIIn.Input(doneCtx, opts)
if err != nil && err != context.Canceled && stopCtx.Err() != context.Canceled {
    return fmt.Errorf("Error asking %s: %w", opts.Id, err)
}

Prevention

When it happens

Trigger: confirm() calls op.UIIn.Input(doneCtx, opts) to read the user's typed confirmation; the call errors with something other than context.Canceled (e.g. io.EOF from a closed stdin, a broken terminal, or an embedded UI implementation returning an error). opts.Id is interpolated so the message names which prompt failed.

Common situations: Piping input or running in CI without a TTY where the prompt can't be answered; stdin closed unexpectedly; a wrapper tool's interactive UI broke; pressing Ctrl-D (EOF) at the prompt instead of typing yes/override.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/98e7a2cac396ffe1. Report an issue: GitHub.