{"record":{"id":"d608ee31f86de656","repo":"denoland/deno","slug":"attempted-to-read-snapshot-data-out-of-range-id","errorCode":null,"errorMessage":"Attempted to read snapshot data out of range: {id} (of {})","messagePattern":"Attempted to read snapshot data out of range: (.+?) \\(of (.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"libs/core/runtime/snapshot.rs","lineNumber":73,"sourceCode":"  data.into_boxed_slice()\n}\n\n#[derive(Default)]\npub struct SnapshotLoadDataStore {\n  data: Vec<Option<v8::Global<v8::Data>>>,\n}\n\nimpl SnapshotLoadDataStore {\n  pub fn get<'s, 'i, T>(\n    &mut self,\n    scope: &mut v8::PinScope<'s, 'i>,\n    id: SnapshotDataId,\n  ) -> v8::Global<T>\n  where\n    v8::Local<'s, T>: TryFrom<v8::Local<'s, v8::Data>>,\n  {\n    let Some(data) = self.data.get_mut(id as usize) else {\n      panic!(\n        \"Attempted to read snapshot data out of range: {id} (of {})\",\n        self.data.len()\n      );\n    };\n    let Some(data) = data.take() else {\n      panic!(\"Attempted to read the snapshot data at index {id} twice\");\n    };\n    let local = v8::Local::new(scope, data);\n    let local = v8::Local::<T>::try_from(local).unwrap_or_else(|_| {\n      panic!(\n        \"Invalid data type at index {id}, expected '{}'\",\n        std::any::type_name::<T>()\n      )\n    });\n    v8::Global::new(scope, local)\n  }\n}\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/libs/core/runtime/snapshot.rs#L55-L91","documentation":"When a JsRuntime boots from a startup snapshot, load_snapshotted_data_from_snapshot rebuilds a SnapshotLoadDataStore, and extensions pull their snapshotted state out of it by index (SnapshotDataId, jsruntime.rs:1058+). get() panics \"out of range\" when an extension requests an id at or beyond the number of entries the snapshot actually stored. That means the extension/state layout at runtime no longer matches the layout that existed when the snapshot was created.","triggerScenarios":"Adding, removing, or reordering extensions that carry snapshot state between create_snapshot and runtime startup; loading a startup snapshot built by a different deno_core/deno_runtime version with a different state layout; concatenating or hand-editing snapshot blobs.","commonSituations":"Bumping deno_core or an extension crate version without regenerating the startup snapshot; feature flags that conditionally include an extension in the runtime but not in the snapshot build (or vice versa); CI caching a stale snapshot artifact.","solutions":["Regenerate the startup snapshot so the stored state list matches the runtime's extension layout","Make the extension vector (set and order) identical between create_snapshot options and RuntimeOptions at boot","Wire create_snapshot's returned files into cargo:rerun-if-changed so the snapshot rebuilds whenever extension inputs change","Pin deno_core and all extension crates to the same versions on both sides"],"exampleFix":"// before: snapshot built with [ext_a, ext_b], runtime boots [ext_a, ext_c, ext_b]\nlet rt = JsRuntime::new(RuntimeOptions {\n  extensions: vec![ext_a(), ext_c(), ext_b()],\n  startup_snapshot: Some(&SNAP),\n  ..Default::default()\n});\n\n// after: same vector (order included) in build.rs and at boot\n// build.rs: create_snapshot(CreateSnapshotOptions { extensions: vec![ext_a(), ext_c(), ext_b()], .. })\nlet rt = JsRuntime::new(RuntimeOptions {\n  extensions: vec![ext_a(), ext_c(), ext_b()],\n  startup_snapshot: Some(&REBUILT_SNAP),\n  ..Default::default()\n});","handlingStrategy":"validation","validationCode":"// Stamp the extension layout into the snapshot artifact and check it before boot.\nconst SNAPSHOT_LAYOUT: &str = \"ext-a:1,ext-c:2,ext-b:3\"; // generated in build.rs\nfn assert_layout(snapshot_tag: &str) {\n  assert_eq!(snapshot_tag, SNAPSHOT_LAYOUT,\n    \"extension layout changed; regenerate the startup snapshot\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the extension vector (names and order) identical in create_snapshot and RuntimeOptions","Regenerate the snapshot whenever an extension with snapshot state is added, removed, or reordered","Treat snapshot and binary as one unit in CI: build, store, and deploy them together","Disable CI caching of snapshot artifacts across dependency bumps"],"tags":["deno-core","snapshot","extensions","version-skew","panic"],"backgroundTag":"snapshot-data-mismatch","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}