databendlabs/databend · error

Expected to ignore a byte

Error message

Expected to ignore a byte

What it means

CursorReadBytesExt::must_ignore is the fallible variant of ignore(f): it advances the cursor past the next byte if and only if that byte satisfies predicate f. If ignore returns false (EOF or predicate mismatch), it raises an InvalidData io error, since a required byte could not be skipped.

Solutions

  1. Inspect the input at the cursor position to see which byte was expected versus found.
  2. Use the non-panicking ignore(f) first if the byte is optional.
  3. Fix the producer so it emits the required byte/padding.

Example fix

// before
cursor.must_ignore(|b| b == b',')?;

// after
if !cursor.ignore(|b| b == b',') {
    // handle optional separator
}
Defensive patterns

Strategy: validation

Validate before calling

if cursor.eof() || !pred_matches_next_byte(cursor) {
    return Err(anyhow!("expected separator byte"));
}

Try / catch

if let Err(e) = cursor.must_ignore(|b| b == b';') {
    return Err(anyhow!("parse failed at offset: {}", e));
}

Prevention

When it happens

Trigger: Calling must_ignore(pred) on a cursor whose next byte does not match pred, or when the cursor is already at EOF.

Common situations: Parsing a structured binary/text format where a mandatory separator or padding byte is absent — often due to malformed input data or an off-by-one in the writer.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/4fdb457874c6f4c9. Report an issue: GitHub.

Appendix: source

Thrown at src/common/io/src/cursor_ext/cursor_read_bytes_ext.rs:37

use std::io::Result;

pub trait ReadBytesExt {
    fn peek(&self) -> Option<char>;
    fn peek_byte(&self) -> Option<u8>;
    fn ignore(&mut self, f: impl Fn(u8) -> bool) -> bool;
    fn ignores(&mut self, f: impl Fn(u8) -> bool) -> usize;
    fn ignore_byte(&mut self, b: u8) -> bool;
    fn ignore_bytes(&mut self, bs: &[u8]) -> bool;
    fn ignore_insensitive_bytes(&mut self, bs: &[u8]) -> bool;
    fn ignore_white_spaces_or_comments(&mut self) -> bool;
    fn ignore_comment(&mut self) -> bool;
    fn until(&mut self, delim: u8, buf: &mut Vec<u8>) -> usize;
    fn keep_read(&mut self, buf: &mut Vec<u8>, f: impl Fn(u8) -> bool) -> usize;
    fn eof(&mut self) -> bool;
    fn must_eof(&mut self) -> Result<()>;
    fn must_ignore(&mut self, f: impl Fn(u8) -> bool) -> Result<()> {
        if !self.ignore(f) {
            return Err(std::io::Error::new(
                ErrorKind::InvalidData,
                "Expected to ignore a byte",
            ));
        }
        Ok(())
    }

    fn must_ignore_byte(&mut self, b: u8) -> Result<()>;

    fn must_ignore_bytes(&mut self, bs: &[u8]) -> Result<()> {
        if !self.ignore_bytes(bs) {
            return Err(std::io::Error::new(
                ErrorKind::InvalidData,
                format!("Expected to have bytes {:?}", bs),
            ));
        }
        Ok(())
    }

View on GitHub (pinned to 288d84d76e)