nautechsystems/nautilus_trader · error

record snapshot anchor: {e}

Error message

record snapshot anchor: {e}

What it means

The event-store kernel's snapshot-anchor callback computes a content hash for a cache snapshot and asks the writer to persist the anchor (blob reference + hash); any error from record_snapshot_anchor is wrapped as "record snapshot anchor: {e}". This means the durable record linking a snapshot to its content hash could not be written, so the snapshot may be unusable on recovery.

Source

Thrown at crates/event_store/src/kernel.rs:359

    pub fn high_watermark(&self) -> u64 {
        self.writer.as_ref().map_or(0, |w| w.high_watermark())
    }

    /// Returns a snapshot anchorer bound to the open writer.
    ///
    /// The execution engine installs this callback while the run is open. The callback
    /// records the cache-owned snapshot reference against the writer's durable
    /// high-watermark after flushing earlier captured entries.
    #[must_use]
    pub fn snapshot_anchorer(&self) -> Option<SnapshotAnchorer> {
        let writer = Arc::clone(self.writer.as_ref()?);

        Some(Rc::new(move |snapshot_ref: CacheSnapshotRef| {
            let content_hash = compute_snapshot_content_hash(snapshot_ref.blob.as_ref());
            writer
                .record_snapshot_anchor(snapshot_ref.blob_ref, content_hash)
                .map(|_| ())
                .map_err(|e| anyhow::anyhow!("record snapshot anchor: {e}"))
        }))
    }

    /// Returns the live bus capture adapter, when one was wired into this run.
    ///
    /// `None` after [`Self::close`] consumes the writer.
    #[must_use]
    pub fn adapter(&self) -> Option<&Arc<BusCaptureAdapter>> {
        self.adapter.as_ref()
    }

    /// Submits the terminal `RunEnded` entry, drains pending entries, and seals the
    /// manifest as [`RunStatus::Ended`].
    ///
    /// Consumes the inner writer; subsequent calls return without effect.
    ///
    /// # Errors
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the source error inside the wrapper message for the real cause (I/O vs closed writer vs bad blob_ref).
  2. Ensure snapshot_anchorer is only invoked while the kernel/writer is still open (before close()).
  3. Check disk space and write permissions on the event-store storage location.
  4. Retry the snapshot write after verifying the blob reference is valid and the store is healthy.
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the writer is still open before snapshotting
if kernel.is_closed() {
    return Err(anyhow::anyhow!("cannot record snapshot anchor: writer closed"));
}

Try / catch

match writer.record_snapshot_anchor(blob_ref, hash) {
    Ok(_) => (),
    Err(e) => log::error!("record snapshot anchor: {e}"), // inspect inner cause
}

Prevention

When it happens

Trigger: Invoking snapshot_anchorer's callback with a CacheSnapshotRef when the underlying writer fails to record the anchor — e.g. the writer is closed/consumed, the blob reference is invalid, or the backing storage write fails.

Common situations: Writing a snapshot after kernel.close() already consumed the writer; disk full or I/O permission problems on the event-store directory; corrupt/unknown blob_ref passed from the cache snapshotter.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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