valeriansaliou/sonic · error · std::io::Error

InvalidData

Error message

InvalidData

What it means

io_error_invalid_data is the library's helper that wraps any parse/conversion failure into std::io::Error with ErrorKind::InvalidData. It is used by parse_line, connect, parse and FromStr implementations when a server reply or configured value cannot be decoded into the expected type. The inner error carries the concrete cause.

Source

Thrown at client/src/util.rs:11

// Sonic
//
// Fast, lightweight and schema-less search backend
// Copyright: 2026, Rémi Bardon <remi@remibardon.name>
// License: Mozilla Public License v2.0 (MPL v2.0)

pub(crate) mod errors {
    pub fn io_error_invalid_data<E: Into<Box<dyn std::error::Error + Send + Sync>>>(
        error: E,
    ) -> std::io::Error {
        std::io::Error::new(std::io::ErrorKind::InvalidData, error)
    }
}

/// Builds a command String efficiently.
#[cfg_attr(feature = "raw-api", macro_export)]
macro_rules! make_command {
    ($command:literal) => {{
        $crate::Command::from($command)
    }};

    ($format:literal $(, $arg:ident)* $(; text: $text:ident)? $(; options: $options:ident)?) => {{
        use std::fmt::Write as _;

        $(let $arg: &str = $arg.as_ref();)*
        $(let $text: &str = $text.as_ref();)?

        // NOTE: Since we can’t know if the argument will be quoted or not,
        //   this macro is a bit too generic and might waste a few bytes of

View on GitHub (pinned to e6a72da6a5)

Solutions

  1. Inspect the error's source/inner payload to see the exact parse failure and raw input.
  2. Confirm client and server protocol versions match.
  3. Parse with the correct target type; e.g. don't FromStr an integer field into a float-only format.
  4. Log raw responses (raw-api feature) to identify format deviations before parsing.

Example fix

// before
let n: u64 = value.parse()?; // opaque InvalidData on bad input
// after
let n: u64 = value.parse().map_err(|e| {
    eprintln!("failed to parse {:?} as u64: {}", value, e);
    e
})?;
Defensive patterns

Strategy: validation

Validate before calling

fn parse_u64_field(raw: &str) -> std::io::Result<u64> {
    raw.trim().parse::<u64>().map_err(|e|
        std::io::Error::new(
            std::io::ErrorKind::InvalidData,
            format!("unexpected field {:?}: {}", raw, e),
        )
    )
}

Type guard

fn is_invalid_data(e: &std::io::Error) -> bool {
    e.kind() == std::io::ErrorKind::InvalidData
}

Try / catch

match channel.get("counter").await {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
        // inspect e.get_ref() / e.source() for the raw failing payload
        log::error!("unparsable response: {}", e);
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling any typed command whose response fails to parse (parse_line/parse), constructing a connection via connect with malformed input, or parsing a value with the type's FromStr impl when the text does not match the expected format.

Common situations: Server/client version mismatch producing unexpected reply formats; reading a value written as one type and parsed as another; corrupted or truncated line-oriented responses; whitespace/encoding differences in server output.

Related errors


AI-assisted analysis of valeriansaliou/sonic@e6a72da6a5 (2026-09-01). Data as JSON: /api/errors/554d16e3e874f126. Report an issue: GitHub.