Kuberwastaken/claurst · error
Stdin closed unexpectedly
Error message
Stdin closed unexpectedly
What it means
The manual-paste branch of the auth-code wait loop maps a closed stdin stream to this error. paste_rx (the stdin line stream) ended with None before the user pasted the '<code>#<state>' string, so there is no code to extract.
Solutions
- Run the login command in an interactive terminal with a live stdin.
- Paste the full '<code>#<state>' value from the browser within 120 seconds instead of closing stdin.
- Avoid piping the login command; if piped, feed the code via the piped input explicitly.
- Use the loopback callback path (allow the localhost redirect_uri) so stdin is not required.
Example fix
// before $ claurst login < /dev/null // after $ claurst login # run interactively, paste the code#state line
Defensive patterns
Strategy: validation
Validate before calling
// only take the interactive paste path when stdin is a TTY
if !stdin_is_tty() {
bail!("manual code paste requires an interactive terminal");
} Try / catch
// handle EOF distinctly so users know stdin died
match paste_rx.await {
Ok(Some(line)) => Ok(line),
Ok(None) | Err(_) => Err(anyhow!("Stdin closed unexpectedly")),
} Prevention
- Run login commands in an interactive terminal; never redirect stdin from /dev/null
- Paste the full code#state value promptly (120s window)
- Prefer the loopback callback path when available
When it happens
Trigger: In the tokio::select! in wait_for_auth_code_impl, the paste_rx branch completes with None: stdin reached EOF (user pressed Ctrl-D, piped input exhausted, or stdin detached in a headless/CI environment) within the 120-second window.
Common situations: Running the login flow in CI or a non-interactive shell where stdin is /dev/null; piping the command; pressing Ctrl-D instead of pasting; terminal emulator detaching mid-flow.
Related errors
- Missing code or state in OAuth callback
- Failed to bind port
- OAuth callback timeout (5 minutes)
- Failed to accept connection
- No query string in callback
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/95dba7ad0283729d.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/cli/src/oauth_flow.rs:537
let trimmed = line.trim().to_string();
if !trimmed.is_empty() {
let _ = paste_tx.send(trimmed);
}
}
});
tokio::select! {
result = cb_rx => {
// Loopback callback: code came clean from the query string and was
// authorized against the localhost redirect_uri.
result
.unwrap_or_else(|_| Err(anyhow::anyhow!("Callback server dropped")))
.map(|code| (code, false))
}
code = paste_rx => {
// Manual paste: the page hands back "<code>#<state>"; keep only the
// code part. This path authorized against MANUAL_REDIRECT_URL.
let raw = code.map_err(|_| anyhow::anyhow!("Stdin closed unexpectedly"))?;
let code_only = raw.split('#').next().unwrap_or(&raw).trim().to_string();
Ok((code_only, true))
}
_ = tokio::time::sleep(Duration::from_secs(120)) => {
bail!("Authentication timed out after 120 seconds")
}
}
}
View on GitHub (pinned to b0637c97ec)