{"record":{"id":"d2948d94942b8673","repo":"spacedriveapp/spacedrive","slug":"arena-index-mismatch-expected-got","errorCode":null,"errorMessage":"Arena index mismatch: expected {}, got {}","messagePattern":"Arena index mismatch: expected (.+?), got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/src/ops/indexing/ephemeral/snapshot.rs","lineNumber":222,"sourceCode":"\t\tfor &id in ids {\n\t\t\tregistry.insert(interned, id);\n\t\t}\n\t}\n\n\t// Rebuild arena (convert SerializableFileNode back to FileNode)\n\tlet mut arena = super::NodeArena::new()?;\n\tfor (expected_idx, serializable_node) in snapshot.arena_entries {\n\t\t// Intern the name and create NameRef\n\t\tlet interned_name = cache.intern(&serializable_node.name);\n\t\tlet name_ref = super::types::NameRef::new(interned_name, serializable_node.parent);\n\n\t\t// Reconstruct FileNode\n\t\tlet mut file_node = super::types::FileNode::new(name_ref, serializable_node.meta);\n\t\tfile_node.children = serializable_node.children;\n\n\t\tlet actual_idx = arena.insert(file_node)?;\n\t\tif actual_idx.as_usize() != expected_idx {\n\t\t\tanyhow::bail!(\n\t\t\t\t\"Arena index mismatch: expected {}, got {}\",\n\t\t\t\texpected_idx,\n\t\t\t\tactual_idx.as_usize()\n\t\t\t);\n\t\t}\n\t}\n\n\t// Reconstruct index using constructor\n\tlet index = super::EphemeralIndex::from_snapshot_parts(\n\t\tarena,\n\t\tcache,\n\t\tregistry,\n\t\tsnapshot.path_index,\n\t\tsnapshot.entry_uuids,\n\t\tsnapshot.content_kinds,\n\t\tsnapshot.stats,\n\t);\n","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/indexing/ephemeral/snapshot.rs#L204-L240","documentation":"While deserializing an ephemeral index snapshot, each serialized node is re-inserted into a fresh NodeArena and the returned index is compared against the index the node had when serialized. A mismatch means the arena's allocation order changed between serialize and load: the snapshot is corrupt, was written by a different arena implementation, or the intern/parent layout shifted. The snapshot cannot be trusted for path resolution.","triggerScenarios":"Loading a snapshot written by an older/newer build whose NodeArena insert logic or node ordering differs; truncated or partially-written snapshot file; snapshot written while concurrent inserts mutated the arena.","commonSituations":"Daemon binary upgraded across a snapshot-format change; crash during snapshot write leaving a torn file; two processes sharing one snapshot path.","solutions":["Delete the ephemeral snapshot cache so it is rebuilt from a fresh scan (ephemeral data is rebuildable by design)","Bump and check a snapshot format version so mismatches are detected explicitly instead of via index comparison","Write snapshots atomically (temp file + rename) so torn files never appear"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Check the snapshot format version before deserializing\nif snapshot.format_version != EXPECTED_SNAPSHOT_VERSION {\n    // stale/incompatible snapshot: delete and rebuild instead of loading\n    std::fs::remove_file(&snapshot_path)?;\n}","typeGuard":null,"tryCatchPattern":"match load_snapshot(&path).await {\n    Ok(index) => index,\n    Err(e) if e.to_string().contains(\"Arena index mismatch\") => {\n        // ephemeral data is rebuildable: discard and rescan\n        let _ = std::fs::remove_file(&path);\n        rebuild_ephemeral_index_from_scan().await?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Write snapshots atomically (temp file + rename) to avoid torn files","Embed and verify a format version and checksum in every snapshot","Treat ephemeral snapshots as a disposable cache: always be able to rebuild from a scan"],"tags":["ephemeral-index","snapshot","serialization","corruption","indexing"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}