sinelaw/fresh · error

Failed to set stdin to CONIN$

Error message

Failed to set stdin to CONIN$: {}

What it means

After successfully opening CONIN$, the editor calls SetStdHandle(STD_INPUT_HANDLE, conin_handle) to make it the process stdin. A zero return means the swap failed and the last OS error is reported. stdin remains pointing at its previous (possibly non-interactive) source.

Solutions

  1. Retry the SetStdHandle call once and re-check with GetLastError
  2. Fall back to using the opened CONIN$ handle directly for reads instead of swapping the std handle
  3. Verify no concurrent thread is mutating std handles during startup
  4. Log last_os_error to identify the specific Win32 failure and adjust spawning accordingly

Example fix

// before
let success = unsafe { SetStdHandle(STD_INPUT_HANDLE, conin_handle) };
if success == 0 { anyhow::bail!("Failed to set stdin to CONIN$: {}", io::Error::last_os_error()); }
// after
let success = unsafe { SetStdHandle(STD_INPUT_HANDLE, conin_handle) };
if success == 0 {
    eprintln!("SetStdHandle failed ({}); using CONIN$ handle directly", io::Error::last_os_error());
    stdin_for_reads = Some(conin_handle); // fallback path
}
Defensive patterns

Strategy: retry

Validate before calling

let conin = open_conin()?; // ensure the open succeeded before SetStdHandle

Try / catch

if unsafe { SetStdHandle(STD_INPUT_HANDLE, conin) } == 0 {
    eprintln!("SetStdHandle failed: {}", io::Error::last_os_error());
    // fall back to using the handle directly
}

Prevention

When it happens

Trigger: SetStdHandle(STD_INPUT_HANDLE, conin_handle) returns 0 — rare Win32 failure while replacing the process's stdin handle slot.

Common situations: Corrupted process handle table, conflicting handle redirections done by the spawning process, or an antivirus/security product intercepting handle manipulation.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/5ee0522e27926546. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/src/main.rs:841

        CreateFileW(
            conin.as_ptr(),
            FILE_GENERIC_READ,
            FILE_SHARE_READ,
            std::ptr::null(),
            OPEN_EXISTING,
            0,
            std::ptr::null_mut(),
        )
    };

    if conin_handle == INVALID_HANDLE_VALUE {
        anyhow::bail!("Failed to open CONIN$: {}", io::Error::last_os_error());
    }

    // Replace stdin with the console input handle
    let success = unsafe { SetStdHandle(STD_INPUT_HANDLE, conin_handle) };
    if success == 0 {
        anyhow::bail!(
            "Failed to set stdin to CONIN$: {}",
            io::Error::last_os_error()
        );
    }

    Ok(())
}

fn handle_first_run_setup(
    editor: &mut Editor,
    args: &Args,
    file_locations: &[FileLocation],
    show_file_explorer: bool,
    stdin_stream: &mut Option<StdinStreamState>,
    workspace_enabled: bool,
) -> AnyhowResult<()> {
    if let Some(log_path) = &args.event_log {
        tracing::trace!("Event logging enabled: {}", log_path.display());

View on GitHub (pinned to 67894ca546)