Hmbown/CodeWhale · error · io::Error

request exceeds bytes

Error message

request exceeds {MAX_REQUEST_BYTES} bytes

What it means

read_request_line accumulates the control-socket request until a newline, enforcing MAX_REQUEST_BYTES. If the line grows past that cap before terminating, it returns InvalidData with 'request exceeds {MAX_REQUEST_BYTES} bytes' to bound memory from oversized or malicious input.

Solutions

  1. Shorten the request payload below MAX_REQUEST_BYTES
  2. Ensure the client terminates each request with a newline ('\n')
  3. Verify the client is speaking the control socket's line-based protocol, not another format
  4. If larger payloads are legitimately needed, raise MAX_REQUEST_BYTES in control_socket.rs and rebuild

Example fix

// before: one huge line
socket.write_all(payload.as_bytes())?; // payload > MAX_REQUEST_BYTES, no '\n'
// after
assert!(payload.len() < MAX_REQUEST_BYTES);
socket.write_all(payload.as_bytes())?;
socket.write_all(b"\n")?;
Defensive patterns

Strategy: validation

Validate before calling

if payload.len() + 1 > MAX_REQUEST_BYTES {
    return Err("request payload too large for control socket".into());
}

Try / catch

match send_request(&mut socket, payload) {
    Err(e) if e.kind() == io::ErrorKind::InvalidData => {
        eprintln!("request rejected: exceeds {} bytes", MAX_REQUEST_BYTES);
    }
    other => other?,
}

Prevention

When it happens

Trigger: A client sends a request line longer than MAX_REQUEST_BYTES without a newline — either a malformed client, a non-protocol client writing binary garbage, or a genuinely oversized command payload.

Common situations: Pointing a tool at the control socket that speaks a different protocol; a bug where the client never terminates the line with \n; attempted abuse of an exposed socket.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/2f426205d1254014. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/control_socket.rs:887

    if read == 0 {
        return Ok(None); // EOF before any content
    }
    if line.last() != Some(&b'\n') {
        // The frame exceeded the cap (or was torn mid-line). Discard the
        // remainder so a well-behaved client finishes its write and reads
        // the rejection; a torn frame's write lands nowhere and is ignored.
        let mut buf = [0u8; 8192];
        loop {
            match stream.read(&mut buf) {
                Ok(0) | Err(_) => break,
                Ok(n) => {
                    if buf[..n].contains(&b'\n') {
                        break;
                    }
                }
            }
        }
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("request exceeds {MAX_REQUEST_BYTES} bytes"),
        ));
    }
    Ok(Some(String::from_utf8_lossy(&line).into_owned()))
}

#[cfg(unix)]
fn write_response_line(stream: &mut UnixStream, value: &str) {
    let _ = writeln!(stream, "{value}");
    let _ = stream.flush();
}

#[cfg(test)]
mod tests {
    use super::*;

    // ── Verb parsing ──────────────────────────────────────────────────────

View on GitHub (pinned to 73e0f67d83)