{"record":{"id":"95dba7ad0283729d","repo":"Kuberwastaken/claurst","slug":"stdin-closed-unexpectedly","errorCode":null,"errorMessage":"Stdin closed unexpectedly","messagePattern":"Stdin closed unexpectedly","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-rust/crates/cli/src/oauth_flow.rs","lineNumber":537,"sourceCode":"            let trimmed = line.trim().to_string();\r\n            if !trimmed.is_empty() {\r\n                let _ = paste_tx.send(trimmed);\r\n            }\r\n        }\r\n    });\r\n\r\n    tokio::select! {\r\n        result = cb_rx => {\r\n            // Loopback callback: code came clean from the query string and was\r\n            // authorized against the localhost redirect_uri.\r\n            result\r\n                .unwrap_or_else(|_| Err(anyhow::anyhow!(\"Callback server dropped\")))\r\n                .map(|code| (code, false))\r\n        }\r\n        code = paste_rx => {\r\n            // Manual paste: the page hands back \"<code>#<state>\"; keep only the\r\n            // code part. This path authorized against MANUAL_REDIRECT_URL.\r\n            let raw = code.map_err(|_| anyhow::anyhow!(\"Stdin closed unexpectedly\"))?;\r\n            let code_only = raw.split('#').next().unwrap_or(&raw).trim().to_string();\r\n            Ok((code_only, true))\r\n        }\r\n        _ = tokio::time::sleep(Duration::from_secs(120)) => {\r\n            bail!(\"Authentication timed out after 120 seconds\")\r\n        }\r\n    }\r\n}\r\n","sourceCodeStart":519,"sourceCodeEnd":546,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/cli/src/oauth_flow.rs#L519-L546","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n$ claurst login < /dev/null\n// after\n$ claurst login   # run interactively, paste the code#state line","handlingStrategy":"validation","validationCode":"// only take the interactive paste path when stdin is a TTY\nif !stdin_is_tty() {\n    bail!(\"manual code paste requires an interactive terminal\");\n}","typeGuard":null,"tryCatchPattern":"// handle EOF distinctly so users know stdin died\nmatch paste_rx.await {\n    Ok(Some(line)) => Ok(line),\n    Ok(None) | Err(_) => Err(anyhow!(\"Stdin closed unexpectedly\")),\n}","preventionTips":["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"],"tags":["oauth","stdin","interactive","cli"],"backgroundTag":"stdin-closed-unexpectedly","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}