atuinsh/atuin · error
Failed to read from input
Error message
Failed to read from input
What it means
When `atuin account change-password` runs without --current-password, it prompts via rpassword::prompt_password, which reads a hidden password from the terminal. If the read fails — stdin closed (EOF, /dev/null), no controlling TTY, or an I/O error — the expect panics with 'Failed to read from input'.
Source
Thrown at crates/atuin/src/command/client/account/change_password.rs:33
#[clap(long, short)]
pub new_password: Option<String>,
/// The two-factor authentication code for your account, if any
#[clap(long, short)]
pub totp_code: Option<String>,
}
impl Cmd {
pub async fn run(&self, settings: &Settings) -> Result<()> {
if !settings.logged_in().await? {
bail!("You are not logged in");
}
let client = auth::auth_client(settings).await;
let current_password = self.current_password.clone().unwrap_or_else(|| {
prompt_password("Please enter the current password: ")
.expect("Failed to read from input")
});
if current_password.is_empty() {
bail!("please provide the current password");
}
let new_password = self.new_password.clone().unwrap_or_else(|| {
prompt_password("Please enter the new password: ").expect("Failed to read from input")
});
if new_password.is_empty() {
bail!("please provide a new password");
}
let mut totp_code = self.totp_code.clone();
loop {
let response = clientView on GitHub (pinned to 202f6ad98e)
Solutions
- Pass the values as flags: atuin account change-password --current-password "$OLD" --new-password "$NEW"
- Run the command in an interactive terminal (docker run -it / docker exec -it)
- If driving the prompt from a pipe, supply a newline-terminated line and keep stdin open until the command exits
Example fix
# before — panics: no TTY, stdin empty atuin account change-password < /dev/null # after — headless flags atuin account change-password --current-password "$OLD" --new-password "$NEW"
Defensive patterns
Strategy: validation
Validate before calling
use std::io::IsTerminal;
let has_flag = std::env::args().any(|a| a.starts_with("--current-password"));
if !has_flag && !std::io::stdin().is_terminal() {
eprintln!("change-password needs --current-password when stdin is not a TTY");
std::process::exit(2);
} Try / catch
let current_password = match rpassword::prompt_password("Please enter the current password: ") {
Ok(pw) => pw,
Err(e) => {
eprintln!("cannot read password (stdin/TTY unavailable): {e}");
std::process::exit(2);
}
}; Prevention
- In scripts and CI, always pass credentials via flags instead of relying on prompts
- Allocate a TTY (docker -it, pty wrapper) when interactive prompts must run
- Fail fast on non-TTY stdin before invoking interactive subcommands
When it happens
Trigger: Running `atuin account change-password` without --current-password in a non-interactive context: stdin redirected from /dev/null or an exhausted pipe, or no TTY attached (cron, CI, docker run/exec without -t).
Common situations: Automation scripts that forgot the flag; CI pipelines; docker exec into containers without a TTY; piping empty input into atuin.
Related errors
- Failed to read from input
- failed to create client
- Failed to compute stats
- bug in list query. please report
- bug in search query. please report
AI-assisted analysis of atuinsh/atuin@202f6ad98e (2026-08-16).
Data as JSON: /api/errors/4f2cdb6f50b3bf75.
Report an issue: GitHub.