{"record":{"id":"d219f6b49870423f","repo":"sinelaw/fresh","slug":"failed-to-get-stdin-handle","errorCode":null,"errorMessage":"Failed to get stdin handle","messagePattern":"Failed to get stdin handle","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/main.rs","lineNumber":750,"sourceCode":"    // SAFETY: `pipe_fd` is a valid descriptor this function just created and\n    // hands sole ownership of to the returned `File`.\n    Ok(unsafe { std::fs::File::from_raw_fd(pipe_fd) })\n}\n\n/// Windows counterpart of [`take_stdin_pipe`].\n#[cfg(windows)]\nfn take_stdin_pipe() -> AnyhowResult<std::fs::File> {\n    use std::os::windows::io::FromRawHandle;\n    use windows_sys::Win32::Foundation::{\n        DuplicateHandle, DUPLICATE_SAME_ACCESS, HANDLE, INVALID_HANDLE_VALUE,\n    };\n    use windows_sys::Win32::System::Console::{GetStdHandle, STD_INPUT_HANDLE};\n    use windows_sys::Win32::System::Threading::GetCurrentProcess;\n\n    // SAFETY: plain console/handle queries; every failure is checked below.\n    let stdin_handle = unsafe { GetStdHandle(STD_INPUT_HANDLE) };\n    if stdin_handle == INVALID_HANDLE_VALUE || stdin_handle.is_null() {\n        anyhow::bail!(\"Failed to get stdin handle\");\n    }\n\n    let mut duplicated: HANDLE = std::ptr::null_mut();\n    // SAFETY: duplicating a handle this process owns into this process; the\n    // result is checked and then owned by the `File` below.\n    let ok = unsafe {\n        let me = GetCurrentProcess();\n        DuplicateHandle(\n            me,\n            stdin_handle,\n            me,\n            &mut duplicated,\n            0,\n            0, // not inheritable\n            DUPLICATE_SAME_ACCESS,\n        )\n    };\n    if ok == 0 {","sourceCodeStart":732,"sourceCodeEnd":768,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/main.rs#L732-L768","documentation":"The editor failed to obtain the standard input handle on Windows via GetStdHandle(STD_INPUT_HANDLE). It bails out when the returned handle is INVALID_HANDLE_VALUE or null, since stdin cannot be used or redirected without it. This is a Windows-specific console setup step, typically performed when attaching stdin to a TTY.","triggerScenarios":"Calling GetStdHandle(STD_INPUT_HANDLE) on Windows returns INVALID_HANDLE_VALUE or a null handle, e.g. when the process was started detached from any console (no stdin allocated) or stdin was already closed.","commonSituations":"Launching fresh-editor from a GUI without a console, from a service or scheduled task, or with stdin redirected to a closed handle; running under a runner that detaches the console.","solutions":["Run the editor from a real console session so a stdin handle exists","If detaching is intentional, allocate a console first (AllocConsole) or open CONIN$ directly instead of relying on GetStdHandle","Check how the process is spawned and stop passing STD_ERROR_HANDLE/closed handles as stdin","On non-Windows this code path does not run; verify you are on the expected platform build"],"exampleFix":"// before\nlet stdin_handle = unsafe { GetStdHandle(STD_INPUT_HANDLE) };\n// after\nlet stdin_handle = unsafe { GetStdHandle(STD_INPUT_HANDLE) };\nif stdin_handle == INVALID_HANDLE_VALUE || stdin_handle.is_null() {\n    unsafe { AllocConsole(); }\n    let stdin_handle = unsafe { GetStdHandle(STD_INPUT_HANDLE) };\n    if stdin_handle == INVALID_HANDLE_VALUE || stdin_handle.is_null() {\n        anyhow::bail!(\"Failed to get stdin handle\");\n    }\n}","handlingStrategy":"validation","validationCode":"fn has_stdin_handle() -> bool {\n    let h = unsafe { GetStdHandle(STD_INPUT_HANDLE) };\n    h != INVALID_HANDLE_VALUE && !h.is_null()\n}","typeGuard":"fn is_valid_handle(h: HANDLE) -> bool {\n    h != INVALID_HANDLE_VALUE && !h.is_null()\n}","tryCatchPattern":"match try_setup_stdin() {\n    Ok(()) => {},\n    Err(e) => eprintln!(\"stdin unavailable: {e}\"), // degrade gracefully\n}","preventionTips":["Run GUI-launched processes with a console or allocate one with AllocConsole","Check handle validity with GetConsoleWindow/GetStdHandle before console work","Avoid spawning the editor with closed stdin handles"],"tags":["windows","console","stdin"],"backgroundTag":"file-open-failed","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}