{"record":{"id":"8be562223555fed3","repo":"hashicorp/terraform","slug":"error-asking-s-v-8be562","errorCode":null,"errorMessage":"Error asking %s: %v","messagePattern":"Error asking (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/backend_common.go","lineNumber":507,"sourceCode":"\n\t\t\t\t\tif err == errRunDiscarded {\n\t\t\t\t\t\terr = errApplyDiscarded\n\t\t\t\t\t\tif op.PlanMode == plans.DestroyMode {\n\t\t\t\t\t\t\terr = errDestroyDiscarded\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresult <- err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\tresult <- func() error {\n\t\tv, err := op.UIIn.Input(doneCtx, opts)\n\t\tif err != nil && err != context.Canceled && stopCtx.Err() != context.Canceled {\n\t\t\treturn fmt.Errorf(\"Error asking %s: %v\", opts.Id, err)\n\t\t}\n\n\t\t// We return the error of our parent channel as we don't\n\t\t// care about the error of the doneCtx which is only used\n\t\t// within this function. So if the doneCtx was canceled\n\t\t// because stopCtx was canceled, this will properly return\n\t\t// a context.Canceled error and otherwise it returns nil.\n\t\tif doneCtx.Err() == context.Canceled || stopCtx.Err() == context.Canceled {\n\t\t\treturn stopCtx.Err()\n\t\t}\n\n\t\t// Make sure we cancel the context here so the loop that\n\t\t// checks for external changes to the run is ended before\n\t\t// we start to make changes ourselves.\n\t\tcancel()\n\n\t\tif v != keyword {\n\t\t\t// Retrieve the run again to get its current status.","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/cloud/backend_common.go#L489-L525","documentation":"In the confirm() helper (backend_common.go:504-508), op.UIIn.Input() returned an error while reading the user's interactive response (override confirmation, apply/discard, etc.). The error is not context.Canceled and stopCtx isn't canceled, so it's treated as a genuine input-subsystem failure rather than a clean cancel.","triggerScenarios":"Reached inside the confirm goroutine when Input() fails for a reason other than cancellation, during an interactive prompt (override, apply, destroy). The %s is opts.Id (e.g. 'override', 'approve').","commonSituations":"Input backend (e.g. readline/terminal) failure. Piped/non-interactive stdin when the UI expected a TTY but got EOF. Misconfigured input plugin. OS-level stdin error in CI environments that partially emulate a UI.","solutions":["Ensure an interactive TTY is available when prompts are expected; in CI either provide input or use -auto-approve / -input=false appropriately.","If using -input=false with a prompt-triggering operation, remove the operation that needs confirmation or pre-approve via -auto-approve.","Check the wrapped %v for the specific input error (EOF, read error) and address the stdin source.","Re-run in a proper terminal if the input subsystem errored transiently."],"exampleFix":"// before: CI without TTY triggers interactive prompt\n// -> Error asking override: EOF\nterraform apply\n// after: skip interactive input\nterraform apply -auto-approve   # or -input=false with a pre-approved run","handlingStrategy":"validation","validationCode":"// Ensure interactive input is feasible before prompting.\nfunc canPrompt(op *backendrun.Operation) bool {\n    return op.UIIn != nil && isTTY(os.Stdin)\n}","typeGuard":null,"tryCatchPattern":"// Skip the prompt path when no TTY is present.\nif !canPrompt(op) { return useAutoApproveOrAbort(op) }","preventionTips":["In CI, pass -auto-approve or -input=false to avoid interactive prompts.","Provide a real TTY when interactive confirmation is required.","Detect non-interactive stdin early and fail with a clear message."],"tags":["terraform","input","ui","interactive","cloud-backend"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}