Hmbown/CodeWhale · error

write incomplete reply

Error message

write incomplete reply

What it means

This is a `std::io::Write::write` Err surfaced through `expect('write incomplete reply')`, panicking the test. The library throws it when writing the synthesized terminal escape burst (`/plu` + a truncated OSC 11 reply) to the write end of the test pipe fails. Because the write end is a pipe, failure usually means the read end was already closed (EPIPE) or the descriptor is invalid — the fixture plumbing broke, not the code under test.

Solutions

  1. Ensure the pipe's read half stays alive until after all writes; only `drop(writer)` after writing (as this test does).
  2. Inspect the io::Error kind: BrokenPipe means the reader side was closed first — fix the fixture ordering.
  3. Handle short writes if swapping in a different writer: loop or use write_all so a partial write does not corrupt the burst.

Example fix

// before
writer.write(&burst).expect("write incomplete reply");
// after
writer.write_all(&burst).expect("pipe write half closed before burst was written");
Defensive patterns

Strategy: try-catch

Validate before calling

// verify write half is still open before writing the burst
assert!(matches!(writer.write(&[]), Ok(_)), "pipe write end is closed (EPIPE) before writing burst");

Try / catch

match writer.write(&burst) {
    Ok(n) if n == burst.len() => {},
    Ok(n) => panic!("short write: {n}/{} bytes", burst.len()),
    Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe =>
        panic!("pipe reader was dropped before the burst was written: {e}"),
    Err(e) => panic!("write incomplete reply: {e}"),
}

Prevention

When it happens

Trigger: `writer.write(&burst)` on a `std::io::pipe()` write half after the read half was dropped or closed; writing to an invalid raw fd; or a partial write loop aborted. Any Err from that call panics with this message.

Common situations: Refactoring the test so `drop(reader)` happens before the write; closing the read end in a helper; running under a sandbox where the pipe fd was closed by the environment.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/e23b65654bd7b021. Report an issue: GitHub.

Appendix: source

Thrown at crates/palette/src/osc11_tests.rs:90

        assert_eq!(
            carried, prefix,
            "type-ahead before the reply must be replayable"
        );
        assert_eq!(
            remaining, suffix,
            "the input pump must still receive the exact suffix"
        );
    }
}

#[test]
fn terminal_reply_reader_retains_incomplete_control_reply_separately_from_typeahead() {
    let (reader, mut writer) = std::io::pipe().expect("create isolated input pipe");
    let prefix = b"/plu";
    let incomplete = b"\x1b]11;rgb:1e/1e\r\r";
    let burst = [prefix.as_slice(), incomplete.as_slice()].concat();
    assert_eq!(
        writer.write(&burst).expect("write incomplete reply"),
        burst.len()
    );
    drop(writer);

    let (answered, reply, carried) = read_terminal_reply(
        reader.as_raw_fd(),
        b"\x1b]11;?\x07",
        Duration::from_secs(1),
        false,
    );

    assert!(
        !answered,
        "an unterminated control reply is not a valid answer"
    );
    assert_eq!(
        reply, incomplete,
        "the caller must account for every unreplayable byte"

View on GitHub (pinned to 433685b202)