nautechsystems/nautilus_trader · error · anyhow::Error

position snapshot blob_ref {blob_ref} has invalid frame inde

Error message

position snapshot blob_ref {blob_ref} has invalid frame index: {e}

What it means

parse_position_snapshot_blob_ref splits a cache blob reference of the form '<position_id>:<snapshot_index>' into its parts. If the trailing frame-index segment is not a valid usize, the parse fails and the function bails with this error naming the full blob_ref and the underlying ParseIntError.

Source

Thrown at crates/common/src/cache/position.rs:458

            .collect()
    }
}

fn parse_position_snapshot_blob_ref(blob_ref: &str) -> anyhow::Result<(PositionId, usize)> {
    let Some(rest) = blob_ref.strip_prefix("cache://position-snapshots/") else {
        anyhow::bail!("unsupported cache snapshot blob_ref {blob_ref}");
    };

    let Some((position_id, snapshot_index)) = rest.rsplit_once('/') else {
        anyhow::bail!("malformed position snapshot blob_ref {blob_ref}");
    };

    if position_id.is_empty() {
        anyhow::bail!("position snapshot blob_ref {blob_ref} has empty position id");
    }

    let snapshot_index = snapshot_index.parse::<usize>().map_err(|e| {
        anyhow::anyhow!("position snapshot blob_ref {blob_ref} has invalid frame index: {e}")
    })?;

    Ok((PositionId::new(position_id), snapshot_index))
}

fn decode_position_snapshot_blob(
    position_id: &PositionId,
    blob: &[u8],
) -> anyhow::Result<Position> {
    let snapshot = serde_json::from_slice::<Position>(blob)?;
    let expected_prefix = format!("{}-", position_id.as_str());

    let Some(snapshot_uuid) = snapshot.id.as_str().strip_prefix(&expected_prefix) else {
        anyhow::bail!(
            "position snapshot id {} does not match blob_ref position {position_id}",
            snapshot.id
        );
    };

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the offending blob_ref value and correct it to '<position_id>:<numeric_index>' format.
  2. Check which code wrote the blob_ref — regenerate snapshots with the current nautilus cache writer instead of restoring legacy/corrupt keys.
  3. Validate the blob_ref string with a regex/parse before calling restore_snapshot_blob to fail early with a clearer message.
  4. If keys come from external storage, verify they were not truncated or migrated incorrectly between cache backends.

Example fix

// before
let blob_ref = "POS-001:abc";
restore_snapshot_blob(blob_ref)?; // invalid frame index

// after
let blob_ref = "POS-001:3"; // <position_id>:<usize frame index>
restore_snapshot_blob(blob_ref)?;
Defensive patterns

Strategy: validation

Validate before calling

# Rust
fn is_valid_blob_ref(blob_ref: &str) -> bool {
    blob_ref.rsplit_once(':')
        .map(|(_, idx)| !idx.is_empty() && idx.parse::<usize>().is_ok())
        .unwrap_or(false)
}
// call before restore: assert!(is_valid_blob_ref(blob_ref));

Type guard

fn parse_blob_ref(blob_ref: &str) -> Option<(String, usize)> {
    let (id, idx) = blob_ref.rsplit_once(':')?;
    Some((id.to_string(), idx.parse::<usize>().ok()?))
}

Try / catch

match restore_snapshot_blob(blob_ref) {
    Ok(pos) => {},
    Err(e) if e.to_string().contains("invalid frame index") => {
        tracing::error!("corrupt blob_ref '{}': {e}", blob_ref);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Restoring a position snapshot via restore_snapshot_blob when the blob_ref's index segment is non-numeric or malformed (e.g. 'POS-1:abc', 'POS-1:', 'POS-1:99999999999999999999999' overflowing usize), produced by position_snapshot_frame lookups.

Common situations: Corrupted or hand-edited cache keys; blob_refs written by a different serializer version or another system; overflow when the index exceeds the platform usize range; copy/paste truncating or mangling the key.

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 nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/503d2e1e18b1dfec. Report an issue: GitHub.