{"record":{"id":"503d2e1e18b1dfec","repo":"nautechsystems/nautilus_trader","slug":"position-snapshot-blob-ref-blob-ref-has-invalid","errorCode":null,"errorMessage":"position snapshot blob_ref {blob_ref} has invalid frame index: {e}","messagePattern":"position snapshot blob_ref (.+?) has invalid frame index: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/common/src/cache/position.rs","lineNumber":458,"sourceCode":"            .collect()\n    }\n}\n\nfn parse_position_snapshot_blob_ref(blob_ref: &str) -> anyhow::Result<(PositionId, usize)> {\n    let Some(rest) = blob_ref.strip_prefix(\"cache://position-snapshots/\") else {\n        anyhow::bail!(\"unsupported cache snapshot blob_ref {blob_ref}\");\n    };\n\n    let Some((position_id, snapshot_index)) = rest.rsplit_once('/') else {\n        anyhow::bail!(\"malformed position snapshot blob_ref {blob_ref}\");\n    };\n\n    if position_id.is_empty() {\n        anyhow::bail!(\"position snapshot blob_ref {blob_ref} has empty position id\");\n    }\n\n    let snapshot_index = snapshot_index.parse::<usize>().map_err(|e| {\n        anyhow::anyhow!(\"position snapshot blob_ref {blob_ref} has invalid frame index: {e}\")\n    })?;\n\n    Ok((PositionId::new(position_id), snapshot_index))\n}\n\nfn decode_position_snapshot_blob(\n    position_id: &PositionId,\n    blob: &[u8],\n) -> anyhow::Result<Position> {\n    let snapshot = serde_json::from_slice::<Position>(blob)?;\n    let expected_prefix = format!(\"{}-\", position_id.as_str());\n\n    let Some(snapshot_uuid) = snapshot.id.as_str().strip_prefix(&expected_prefix) else {\n        anyhow::bail!(\n            \"position snapshot id {} does not match blob_ref position {position_id}\",\n            snapshot.id\n        );\n    };","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/cache/position.rs#L440-L476","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the offending blob_ref value and correct it to '<position_id>:<numeric_index>' format.","Check which code wrote the blob_ref — regenerate snapshots with the current nautilus cache writer instead of restoring legacy/corrupt keys.","Validate the blob_ref string with a regex/parse before calling restore_snapshot_blob to fail early with a clearer message.","If keys come from external storage, verify they were not truncated or migrated incorrectly between cache backends."],"exampleFix":"// before\nlet blob_ref = \"POS-001:abc\";\nrestore_snapshot_blob(blob_ref)?; // invalid frame index\n\n// after\nlet blob_ref = \"POS-001:3\"; // <position_id>:<usize frame index>\nrestore_snapshot_blob(blob_ref)?;","handlingStrategy":"validation","validationCode":"# Rust\nfn is_valid_blob_ref(blob_ref: &str) -> bool {\n    blob_ref.rsplit_once(':')\n        .map(|(_, idx)| !idx.is_empty() && idx.parse::<usize>().is_ok())\n        .unwrap_or(false)\n}\n// call before restore: assert!(is_valid_blob_ref(blob_ref));","typeGuard":"fn parse_blob_ref(blob_ref: &str) -> Option<(String, usize)> {\n    let (id, idx) = blob_ref.rsplit_once(':')?;\n    Some((id.to_string(), idx.parse::<usize>().ok()?))\n}","tryCatchPattern":"match restore_snapshot_blob(blob_ref) {\n    Ok(pos) => {},\n    Err(e) if e.to_string().contains(\"invalid frame index\") => {\n        tracing::error!(\"corrupt blob_ref '{}': {e}\", blob_ref);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never hand-edit cache blob_ref keys; always generate them via the cache writer.","Validate external/migrated keys against the '<id>:<usize>' pattern before restore.","Add integrity checks when migrating snapshots between cache backends."],"tags":["cache","parsing","blob-ref","position-snapshot"],"backgroundTag":"invalid-argument-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}