{"record":{"id":"68ec3f41ae84571b","repo":"gleam-lang/gleam","slug":"stdin-read-line","errorCode":null,"errorMessage":"stdin read_line","messagePattern":"stdin read_line","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-cli/src/hex/auth.rs","lineNumber":340,"sourceCode":"fn send_user_to_oauth_verification_url(device_authorisation: &hexpm::OAuthDeviceAuthorisation) {\n    // We make them press Enter to open the browser instead of going there immediately,\n    // to make sure they see the code before the browser window potentially hides the\n    // terminal window.\n    let uri = &device_authorisation.verification_uri;\n    println!(\n        \"Your Hex verification code:\n\n    {code}\n\nVerify this code matches what is shown in your browser.\n\nPress Enter to open {uri}\",\n        code = device_authorisation.user_code,\n    );\n\n    let _ = std::io::stdin()\n        .read_line(&mut String::new())\n        .expect(\"stdin read_line\");\n    if opener::open_browser(uri).is_err() {\n        println!(\"\\nFailed to open the browser, please navigate to {uri}\");\n    }\n}\n\n#[derive(Debug, serde::Serialize, serde::Deserialize)]\nstruct StoredOAuthRepoCredentials {\n    #[serde(with = \"http_serde::uri\")]\n    api: http::Uri,\n    #[serde(with = \"http_serde::uri\")]\n    repository: http::Uri,\n    /// An encrypted refresh token.\n    refresh_token: String,\n    /// The hash of the token, so it can be revoked even if it cannot be encrypted.\n    refresh_token_hash: String,\n}\n\n#[derive(Debug, serde::Serialize, serde::Deserialize)]","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/gleam-lang/gleam/blob/15b07c783065c92bb016b1b74ed0995a5259850f/compiler-cli/src/hex/auth.rs#L322-L358","documentation":"Panic from `.expect(\"stdin read_line\")` in send_user_to_oauth_verification_url in compiler-cli/src/hex/auth.rs. Reading the user's Enter keypress from standard input failed — stdin was closed, redirected from an exhausted/EOF pipe, or an I/O error occurred — so the OAuth device flow panics instead of proceeding to open the browser.","triggerScenarios":"Running the Hex OAuth authentication (`gleam auth`) non-interactively: stdin redirected from /dev/null or a closed pipe, running under CI where no TTY exists, or stdin read interrupted by an I/O error after the device code is displayed.","commonSituations":"CI pipelines invoking gleam auth without a TTY, scripts piping input to the CLI, detached processes whose stdin is closed, or containers run with `< /dev/null`.","solutions":["Run the authentication command in an interactive terminal with stdin attached.","Ignore read failures on stdin (the read is only a pause) instead of panicking: use `let _ = std::io::stdin().read_line(...)` without expect.","Skip the pause entirely when stdin is not a TTY (check with std::io::stdin().is_terminal() via the IsTerminal trait) and open the browser immediately.","Provide a non-interactive mode that prints the verification URL and code without waiting for Enter."],"exampleFix":"// before\nstd::io::stdin()\n    .read_line(&mut String::new())\n    .expect(\"stdin read_line\");\n// after\nif std::io::stdin().is_terminal() {\n    let _ = std::io::stdin().read_line(&mut String::new());\n}","handlingStrategy":"try-catch","validationCode":"use std::io::IsTerminal;\nif !std::io::stdin().is_terminal() { eprintln!(\"non-interactive: skipping Enter prompt\"); }","typeGuard":"fn stdin_is_interactive() -> bool { std::io::IsTerminal::is_terminal(&std::io::stdin()) }","tryCatchPattern":"std::panic::catch_unwind(|| gleam_hex::authenticate())\n    .map_err(|_| anyhow::anyhow!(\"gleam auth panicked waiting on stdin\"))?;","preventionTips":["Only run OAuth device flows in interactive terminals.","Never redirect stdin from /dev/null when calling gleam auth.","Make the prompt tolerant of read errors — it is only a pause.","Offer a non-interactive flag that prints the URL without waiting."],"tags":["rust","stdin","oauth","panic","tty"],"backgroundTag":"file-read-failed","analyzedSha":"15b07c783065c92bb016b1b74ed0995a5259850f","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}