denoland/deno · critical
Attempted to read the snapshot data at index {id} twice
Error message
Attempted to read the snapshot data at index {id} twice What it means
SnapshotLoadDataStore::get moves each snapshotted value out of its slot with Option::take, so a given SnapshotDataId can be consumed exactly once. The panic "read the snapshot data at index {id} twice" fires when the same index is requested again after it was already taken. This is a programming invariant inside extension state deserialization: one state entry must map to exactly one consumer during runtime boot.
Source
Thrown at libs/core/runtime/snapshot.rs:79
}
impl SnapshotLoadDataStore {
pub fn get<'s, 'i, T>(
&mut self,
scope: &mut v8::PinScope<'s, 'i>,
id: SnapshotDataId,
) -> v8::Global<T>
where
v8::Local<'s, T>: TryFrom<v8::Local<'s, v8::Data>>,
{
let Some(data) = self.data.get_mut(id as usize) else {
panic!(
"Attempted to read snapshot data out of range: {id} (of {})",
self.data.len()
);
};
let Some(data) = data.take() else {
panic!("Attempted to read the snapshot data at index {id} twice");
};
let local = v8::Local::new(scope, data);
let local = v8::Local::<T>::try_from(local).unwrap_or_else(|_| {
panic!(
"Invalid data type at index {id}, expected '{}'",
std::any::type_name::<T>()
)
});
v8::Global::new(scope, local)
}
}
#[derive(Default)]
pub struct SnapshotStoreDataStore {
data: Vec<v8::Global<v8::Data>>,
}
impl SnapshotStoreDataStore {View on GitHub (pinned to f7822238ca)
Solutions
- Ensure each snapshot state entry is loaded exactly once per JsRuntime boot; do not re-use the boot SnapshotLoadDataStore for extra realms
- Audit extensions for duplicate state registrations sharing one id
- Regenerate the snapshot after changing any state callback layout
- Align deno_core/extension versions between snapshot creation and consumption
Defensive patterns
Strategy: validation
Prevention
- Consume each snapshot state entry exactly once per runtime boot
- Do not reuse the boot-time SnapshotLoadDataStore when creating extra realms; use fresh per-realm state
- Audit extensions for duplicate registrations of the same snapshot state id
- Regenerate the snapshot after any change to state callbacks
When it happens
Trigger: An extension's state deserialization callback running twice against the same store (e.g. invoked for an extra realm or a second runtime sharing the store); two extensions (or a duplicated state registration) requesting the same SnapshotDataId; custom embeddings that re-run snapshot state loading manually after JsRuntime init already consumed it.
Common situations: Embeddings that create additional realms and reuse the boot-time SnapshotLoadDataStore instead of fresh per-realm state; refactors that accidentally register the same snapshot state type/id twice; version skew changing how many state entries an extension consumes.
Related errors
- Attempted to read snapshot data out of range: {id} (of {})
- Invalid data type at index {id}, expected '{}'
- {path} exists
- unable to convert
- Failed to initialize a JsRuntime: {}
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/a757c542b8706fcf.
Report an issue: GitHub.