rust-lang/rust · error · io::Error

{e:?}: {error}

Error message

{e:?}: {error}

What it means

Wrapped by rust-analyzer's command runner (output_with_lines) when the underlying process spawning/reading fails. It re-wraps the io::Error preserving its kind and formatting both the debug form of the error and any accumulated stdout/stderr error text. Used for flycheck/cargo diagnostics command execution where partial output may already have been parsed.

Source

Thrown at src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs:117

                if let Some(t) = self.parser.from_stderr_line(line, &mut stderr_errors) {
                    self.sender.send(t).unwrap();
                    read_at_least_one_stderr_message = true;
                }
            },
            &mut || {
                if let Some(t) = self.parser.from_eof() {
                    self.sender.send(t).unwrap();
                }
            },
        );

        let read_at_least_one_message =
            read_at_least_one_stdout_message || read_at_least_one_stderr_message;
        let mut error = stdout_errors;
        error.push_str(&stderr_errors);
        match output {
            Ok(_) => Ok((read_at_least_one_message, error)),
            Err(e) => Err(io::Error::new(e.kind(), format!("{e:?}: {error}"))),
        }
    }
}

/// 'Join On Drop' wrapper for a child process.
///
/// This wrapper kills the process when the wrapper is dropped.
struct JodGroupChild(Box<dyn ChildWrapper>);

impl Drop for JodGroupChild {
    fn drop(&mut self) {
        _ = self.0.kill();
        _ = self.0.wait();
    }
}

/// A handle to a shell command, such as cargo for diagnostics (flycheck).
pub(crate) struct CommandHandle<T> {

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Read the {error} portion: it holds captured stdout/stderr lines from the failed command.
  2. Verify the {e:?} portion: if ErrorKind::NotFound, the configured binary is missing - fix checkOnSave.command / PATH.
  3. Run the exact command rust-analyzer logs in a terminal to reproduce the failure directly.
  4. Increase memory/check timeouts if the process is being killed externally.

Example fix

// Configuration fix (settings.json):
// before
"rust-analyzer.check.command": "cargo",
"rust-analyzer.check.extraArgs": ["--offline"]

// after - ensure cargo is found and flags are valid
"rust-analyzer.check.command": "cargo",
"rust-analyzer.check.extraArgs": []
Defensive patterns

Strategy: try-catch

Validate before calling

fn tool_available(cmd: &str) -> bool {
    which::which(cmd).is_ok()
}
// Before flycheck: assert tool_available(&check_command).

Try / catch

match output_with_lines(handle) {
    Ok((read, errs)) => Ok((read, errs)),
    Err(e) => {
        // e.to_string() == "{e:?}: {error}"; parse {e:?} for kind
        if e.kind() == io::ErrorKind::NotFound {
            // fix checkOnSave.command / PATH, surface to user
        }
        Err(e)
    }
}

Prevention

When it happens

Trigger: rust-analyzer invoking an external command (typically cargo check / clippy) that fails to spawn or exits with an IO error while streaming output - e.g. cargo binary missing, command killed, pipe broken. The error chains the original io::Error kind with the captured parser error buffer.

Common situations: cargo or the configured check tool not on PATH; checkOnSave command misconfigured; process killed by OOM or user; antivirus interfering with the spawned tool; disk/pipe errors.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/691ae9ddeebcb2ae. Report an issue: GitHub.