denoland/deno · critical

Invalid data type at index {id}, expected '{}'

Error message

Invalid data type at index {id}, expected '{}'

What it means

After taking a slot, SnapshotLoadDataStore::get casts the stored v8::Data handle to the requested type T with v8::Local::<T>::try_from, and panics "Invalid data type at index {id}, expected '{type}'" (type spelled by std::any::type_name) when the cast fails. The snapshot holds a different v8 kind at that index than the extension now expects — the serialized representation changed between the snapshot producer and consumer.

Source

Thrown at libs/core/runtime/snapshot.rs:83

    &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 {
  pub fn register<T>(&mut self, global: v8::Global<T>) -> SnapshotDataId
  where
    for<'s> v8::Local<'s, v8::Data>: From<v8::Local<'s, T>>,
  {

View on GitHub (pinned to f7822238ca)

Solutions

  1. Regenerate the startup snapshot with the binary's exact deno_core and extension versions
  2. Treat the snapshot blob and the binary as one atomic artifact in CI (build and ship them together)
  3. Clear any cached/committed snapshot files after dependency bumps and rebuild
  4. Verify the version constants stamped into snapshot tooling match the linked crates
Defensive patterns

Strategy: validation

Validate before calling

// Embed a deno_core version marker alongside the snapshot and verify at load.
fn snapshot_matches_runtime(marker: &str) -> bool {
  marker == env!("CARGO_PKG_VERSION_DENO_CORE")
}

Prevention

When it happens

Trigger: A deno_core or extension upgrade changed the v8 type stored for a state index (e.g. an Array where an Object used to be); a snapshot built by a different deno_core version; extensions whose snapshot state format changed without regenerating the snapshot blob.

Common situations: Rolling deployments mixing old snapshot artifacts with new binaries; local dev reusing a committed snapshot file after pulling dependency updates; patch releases that changed internal state shapes.

Related errors


AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20). Data as JSON: /api/errors/9c8954828bbab528. Report an issue: GitHub.