{"record":{"id":"479a5a6db763acac","repo":"facebook/flow","slug":"failed-to-deserialize-docblock","errorCode":null,"errorMessage":"failed to deserialize Docblock","messagePattern":"failed to deserialize Docblock","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_heap_serialization/src/lib.rs","lineNumber":69,"sourceCode":"    let (ast, _): (Program<Loc, Loc>, _) =\n        bincode::serde::decode_from_slice(&decompressed, bincode::config::legacy())\n            .expect(\"failed to deserialize AST\");\n    clear_file_key();\n    Arc::new(ast)\n}\n\npub fn serialize_docblock(docblock: &Docblock) -> Vec<u8> {\n    let bytes = bincode::serde::encode_to_vec(docblock, bincode::config::legacy())\n        .expect(\"failed to serialize Docblock\");\n    compress(&bytes)\n}\n\npub fn deserialize_docblock(file_key: &FileKey, bytes: &[u8]) -> Arc<Docblock> {\n    let decompressed = decompress(bytes);\n    set_file_key(file_key);\n    let (docblock, _): (Docblock, _) =\n        bincode::serde::decode_from_slice(&decompressed, bincode::config::legacy())\n            .expect(\"failed to deserialize Docblock\");\n    clear_file_key();\n    Arc::new(docblock)\n}\n\npub fn serialize_aloc_table(table: &PackedALocTable) -> Vec<u8> {\n    let bytes = bincode::serde::encode_to_vec(table, bincode::config::legacy())\n        .expect(\"failed to serialize PackedALocTable\");\n    compress(&bytes)\n}\n\npub fn deserialize_aloc_table(bytes: &[u8]) -> Arc<PackedALocTable> {\n    let decompressed = decompress(bytes);\n    let (table, _): (PackedALocTable, _) =\n        bincode::serde::decode_from_slice(&decompressed, bincode::config::legacy())\n            .expect(\"failed to deserialize PackedALocTable\");\n    Arc::new(table)\n}\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_heap_serialization/src/lib.rs#L51-L87","documentation":"Panics when bincode fails to decode a Docblock from decompressed bytes. Like the other round-trips in this crate, the file_key thread-local is set for Loc resolution and the tuple returned by decode_from_slice must consume exactly the whole slice. Corruption or schema drift between writer and reader lands here.","triggerScenarios":"deserialize_docblock on cache bytes truncated mid-record or written by a different flow build; a Docblock format change (new field/variant) without cache invalidation; wrong file passed in (bytes are a different record type that happens to decompress).","commonSituations":"Upgrading flow while keeping the old saved-state directory; caches shared across checkout directories with mixed versions; non-atomic cache writes from killed processes.","solutions":["Clear the docblock/heap cache entries so they are recomputed","Keep one cache directory per flow version (version-stamped cache paths)","Regenerate fixtures after changing any serialized type in Docblock"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    flow_heap_serialization::deserialize_docblock(&file_key, &bytes)\n})) {\n    Ok(doc) => doc,\n    Err(_) => { std::fs::remove_file(&cache_path).ok(); reparse_docblock(&file_key)? }\n}","preventionTips":["Clear docblock caches after upgrading flow or changing serialized types","Use atomic writes when saving docblock records","Keep producer and consumer of cache files on the same binary version"],"tags":["rust","bincode","serialization","docblock","saved-state"],"backgroundTag":"bincode-decode-error","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T11:17:13.642Z"}