hashicorp/terraform · error
Error asking
Error message
Error asking %s: %v
What it means
Inside the confirm() goroutine, op.UIIn.Input returned an error that is neither context.Canceled on the done context nor on stopCtx. The backend reports which input id failed ('override', 'approve', etc.) plus the wrapped error.
Solutions
- Provide a real TTY for interactive ops, or use --auto-approve to bypass prompts.
- Ensure stdin is not redirected from /dev/null when prompts are expected.
- For custom UIIn implementations, make Input return context.Canceled on shutdown rather than a raw error.
- Reconnect (e.g. re-attach to tmux/SSH) if the session dropped.
Defensive patterns
Strategy: try-catch
Validate before calling
func interactiveInputAvailable(op *backendrun.Operation) bool {
return op.UIIn != nil && op.UIOut != nil && isTerminal(os.Stdin)
}
// skip prompts in CI: pass --auto-approve Type guard
func isTerminal(f *os.File) bool {
fi, err := f.Stat()
return err == nil && (fi.Mode()&os.ModeCharDevice) != 0
} Try / catch
v, err := op.UIIn.Input(ctx, opts)
if err != nil && err != context.Canceled && ctx.Err() != context.Canceled {
// treat as non-fatal: fall back to default or fail gracefully
return fallback(opts)
} Prevention
- Provide a real TTY for interactive ops; use --auto-approve in CI.
- Do not redirect stdin from /dev/null when prompts are expected.
- Custom UIIn implementations should return context.Canceled on shutdown.
When it happens
Trigger: op.UIIn.Input(doneCtx, opts) returns non-nil, non-canceled err: stdin closed unexpectedly; terminal read failure; input implementation raised an internal error; EOF from a piped/non-interactive stdin.
Common situations: Running an interactive apply inside CI without a TTY; SSH session dropped mid-prompt; stdin redirected from /dev/null or a closed pipe; custom UIIn implementation threw.
Related errors
- Failed to override
- backend does not support key/value tags. Try using key-only…
- Error asking for input to configure backend
- Error asking
- error creating workspace
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/8be562223555fed3.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cloud/backend_common.go:507
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 d32a084675)