nautechsystems/nautilus_trader · error

Invalid `StatMsg`

Error message

Invalid `StatMsg`

What it means

`read_statistics_records` expects each stream record to decode as `dbn::StatMsg`. If `record.get::<StatMsg>()` returns None the loader returns `Invalid \`StatMsg\``, indicating the stream holds records of a different type than statistics.

Source

Thrown at crates/adapters/databento/src/loader.rs:913

            None
        };
        let mut dbn_stream = decoder.decode_stream::<T>();
        let fixed_instrument_id = instrument_id.is_some();
        let mut fixed_price_precision = price_precision;

        // Loop over skipped records so one unsupported stat_type does not terminate
        // the stream; precheck before precision resolution.
        Ok(std::iter::from_fn(move || {
            loop {
                if let Err(e) = dbn_stream.advance() {
                    return Some(Err(e.into()));
                }

                let rec = dbn_stream.get()?;
                let record = dbn::RecordRef::from(rec);
                let msg = match record.get::<dbn::StatMsg>() {
                    Some(m) => m,
                    None => return Some(Err(anyhow::anyhow!("Invalid `StatMsg`"))),
                };

                if !is_supported_stat_type(msg.stat_type) {
                    log::warn!("Skipping unsupported `stat_type` {}", msg.stat_type);
                    continue;
                }

                let instrument_id = match self.resolve_record_instrument_id(
                    &record,
                    instrument_id,
                    &mut metadata_cache,
                ) {
                    Ok(id) => id,
                    Err(e) => return Some(Err(e)),
                };
                let resolved_precision = match self.resolve_stream_price_precision(
                    &instrument_id,
                    fixed_instrument_id,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Download with the statistics schema so records are StatMsg
  2. Confirm the file path passed to `read_statistics_records` points at the statistics export
  3. Process each schema's file separately instead of concatenating DBN files
  4. Inspect the record rtype/dbn header to confirm it is `statistics` before loading
Defensive patterns

Strategy: validation

Validate before calling

assert_eq!(request.schema, "stats", "read_statistics_records requires the statistics schema");

Type guard

fn is_stat_record(rec: &dbn::RecordRef) -> bool {
    rec.get::<dbn::StatMsg>().is_some()
}

Try / catch

for item in loader.read_statistics_records(file, instrument_id) {
    match item {
        Ok(stat) => handle(stat),
        Err(e) if e.to_string().contains("Invalid `StatMsg`") => {
            log::error!("stream is not statistics data: {e}");
            break;
        }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Calling `read_statistics_records` on a DBN file/stream not produced with the `statistics` schema, or a stream where a non-stat record appears (mixed or mislabeled export).

Common situations: Downloading `stats`/statistics data but loading the wrong file; concatenated exports of several schemas.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ae543a7ebf2e7a78. Report an issue: GitHub.