nautechsystems/nautilus_trader · error
Cannot extract snapshot: no events processed yet
Error message
Cannot extract snapshot: no events processed yet
What it means
`extract_snapshot` serializes the profiler's full state (positions, ticks, fee model) into a `PoolSnapshot` for checkpoint/restore. A snapshot includes `last_processed_event` so a restored profiler can resume replay correctly; if no event has ever been processed, there is no resume point, so the method errors instead of producing a snapshot with undefined provenance.
Source
Thrown at crates/model/src/defi/pool_analysis/profiler.rs:1882
/// all liquidity positions, and the full tick distribution into a portable
/// [`PoolSnapshot`] structure. This snapshot can be serialized, persisted
/// to database, or used to restore pool state later.
///
/// # Errors
///
/// Returns an error if no events have been processed yet, since there is no event watermark to
/// anchor the snapshot to.
pub fn extract_snapshot(&self) -> anyhow::Result<PoolSnapshot> {
let positions: Vec<_> = self.positions.values().cloned().collect();
let ticks: Vec<_> = self.tick_map.get_all_ticks().values().copied().collect();
let mut state = self.state.clone();
state.liquidity = self.tick_map.liquidity;
let last_processed_event = self
.last_processed_event
.clone()
.ok_or_else(|| anyhow::anyhow!("Cannot extract snapshot: no events processed yet"))?;
Ok(PoolSnapshot::new(
self.pool.instrument_id,
state,
positions,
ticks,
self.analytics.clone(),
last_processed_event,
self.last_processed_ts.unwrap_or(self.pool.ts_init), // ts_event (last processed event)
self.last_processed_ts.unwrap_or(self.pool.ts_init), // ts_init
))
}
/// Gets the count of positions that are currently active.
///
/// Active positions are those with liquidity > 0 and whose tick range
/// includes the current pool tick (meaning they have tokens in the pool).
#[must_use]View on GitHub (pinned to 18893faf8b)
Solutions
- Process at least one pool event before calling `extract_snapshot`.
- Guard the call: check whether any events were processed and skip/make a fresh snapshot from genesis instead.
- If you need a baseline snapshot of an untouched pool, represent it as 'no snapshot / start from genesis' in your checkpoint scheme.
- In tests, drive the profiler with one synthetic event before extracting a snapshot.
Example fix
// before
let snapshot = profiler.extract_snapshot()?; // Err if nothing processed
// after
let snapshot = match profiler.extract_snapshot() {
Ok(s) => Some(s),
Err(e) if e.to_string().contains("no events processed yet") => None, // start from genesis
Err(e) => return Err(e),
}; Defensive patterns
Strategy: validation
Validate before calling
fn can_snapshot(profiler: &PoolProfiler) -> bool { profiler.last_processed_event.is_some() } Try / catch
let snapshot = profiler.extract_snapshot()
.map(Some)
.or_else(|e| if e.to_string().contains("no events processed yet") { Ok(None) } else { Err(e) })?; Prevention
- Only checkpoint after the replay loop has applied events
- Treat an unprocessed profiler as genesis rather than erroring in your checkpoint layer
- Add an assertion/log when snapshotting early in pipelines
When it happens
Trigger: Calling `extract_snapshot` on a freshly constructed `PoolProfiler` before any event has been applied via `process`/`process_defi_data` — i.e. `last_processed_event` is `None`.
Common situations: Checkpointing logic that runs too early in a replay pipeline; test code snapshotting a newly built profiler; resuming a job whose profiler was rebuilt but not yet fed any events.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Router allowance {allowance} is below the swap amount {} for
- Input token {} balance {balance} is below the swap amount {}
- BacktestNode state is unavailable when dispose_on_completion
- Native currency not specified for chain {}
- Must have the `chain` field set
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1932ce447546e405.
Report an issue: GitHub.