Skip to content
Latchkey

Rust E0277 "the `?` operator can only be used" in CI

You used ? to propagate an error, but the function return type cannot be built from the error you are propagating. rustc reports an unsatisfied From trait bound -- the ? desugars to a From::from that does not exist.

What this error means

The compiler shows error[E0277]: ? couldn't convert the error to MyError` with a note that From<io::Error>` (or similar) is not implemented. It is deterministic.

cargo
error[E0277]: `?` couldn't convert the error to `AppError`
 --> src/load.rs:9:30
  |
9 |     let data = read_file(path)?;
  |                              ^ the trait `From<std::io::Error>` is not implemented for `AppError`
  |
  = note: the question mark operation (`?`) implicitly performs a conversion via `From`

Common causes

No From impl for the source error

The function returns Result<_, AppError>, but AppError has no From<io::Error>, so ? cannot convert the propagated error.

Mismatched error type after a refactor

The return error type changed (or a new error source was introduced) and the conversion path was never added.

How to fix it

Implement From for the error type

Give the error type a conversion from the source error so ? can build it.

src/error.rs
impl From<std::io::Error> for AppError {
    fn from(e: std::io::Error) -> Self { AppError::Io(e) }
}

Derive conversions with thiserror

thiserror generates the From impls for you via #[from].

src/error.rs
#[derive(thiserror::Error, Debug)]
enum AppError {
    #[error("io")] Io(#[from] std::io::Error),
}

How to prevent it

  • Add a From impl whenever a new error source flows through ?.
  • Use thiserror or anyhow to keep conversions consistent.
  • Run cargo check after changing a function return error type.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →