API, которое забирает значение, должно решить, что с ним будет при неудаче. String::from_utf8 принимает Vec<u8> по значению, и при ошибке им владеет сама ошибка.

fn main() {
    let bytes = vec![b'o', b'k', 0xff, b'!'];
    match String::from_utf8(bytes) {
        Ok(s) => println!("{s}"),
        Err(e) => {
            let at = e.utf8_error().valid_up_to();
            let bytes = e.into_bytes();
            println!("bad byte at {at}, {} bytes back", bytes.len());
        }
    }
}

Вывод bad byte at 2, 4 bytes back. Без копирования, вызывающий получает свой буфер и смещение одним значением. mpsc::Sender::send поступает так же, SendError несёт сообщение, которое не удалось доставить.

Альтернатива - ошибка, которая только описывает сбой, и тогда значение уничтожается внутри вызова. Для маленького значения это нормально. Для большого буфера вызывающему остаётся либо клонировать перед каждой попыткой, либо терять данные на пути ошибки, и ни то ни другое не видно в сигнатуре.

Какие ещё API стандартной библиотеки забирают значение и выбрасывают его при ошибке? Короткий список помог бы сверить с ним собственные интерфейсы.