{"id":"8c73372fec7050ac","repo":"rust-lang/rust","slug":"failed-to-convert-defpathhash-def-path-hash","errorCode":null,"errorMessage":"Failed to convert DefPathHash {def_path_hash:?}","messagePattern":"Failed to convert DefPathHash (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_middle/src/query/on_disk_cache.rs","lineNumber":662,"sourceCode":"        let cnum = self.tcx.stable_crate_id_to_crate_num(stable_id);\n        cnum\n    }\n\n    // Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two\n    // compilation sessions. We use the `DefPathHash`, which is stable across\n    // sessions, to map the old `DefId` to the new one.\n    fn decode_def_id(&mut self) -> DefId {\n        // Load the `DefPathHash` which is was we encoded the `DefId` as.\n        let def_path_hash = DefPathHash::decode(self);\n\n        // Using the `DefPathHash`, we can lookup the new `DefId`.\n        // Subtle: We only encode a `DefId` as part of a query result.\n        // If we get to this point, then all of the query inputs were green,\n        // which means that the definition with this hash is guaranteed to\n        // still exist in the current compilation session.\n        match self.tcx.def_path_hash_to_def_id(def_path_hash) {\n            Some(r) => r,\n            None => panic!(\"Failed to convert DefPathHash {def_path_hash:?}\"),\n        }\n    }\n\n    fn decode_attr_id(&mut self) -> rustc_span::AttrId {\n        panic!(\"cannot decode `AttrId` with `CacheDecoder`\");\n    }\n}\n\nimpl<'a, 'tcx> BlobDecoder for CacheDecoder<'a, 'tcx> {\n    fn decode_symbol(&mut self) -> Symbol {\n        self.decode_symbol_or_byte_symbol(\n            Symbol::new,\n            |this| Symbol::intern(this.read_str()),\n            |opaque| Symbol::intern(opaque.read_str()),\n        )\n    }\n\n    fn decode_byte_symbol(&mut self) -> ByteSymbol {","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_middle/src/query/on_disk_cache.rs#L644-L680","documentation":"`CacheDecoder::decode_def_id` (on_disk_cache.rs:662) reads a `DefPathHash` from the cache and calls `tcx.def_path_hash_to_def_id(hash)` to remap it to the current session's `DefId`. A `None` result triggers `panic!(\"Failed to convert DefPathHash {def_path_hash:?}\")`. The cache's contract is that every `DefPathHash` written into a query result corresponds to a definition that still exists in the current session—so a miss means that definition disappeared (item removed/renamed) without proper cache invalidation.","triggerScenarios":"Fires when an incremental-cache record references a `DefId` whose `DefPathHash`—stable across sessions by design—no longer maps to any definition in the live crate metadata. The classic cause is removing, renaming, or relocating an item (fn/type/trait/impl) that another crate's cached query result pointed at, while the incremental DB still considers the dependent query green.","commonSituations":"Very common after refactoring a shared library crate (deleting/renaming public items) while a downstream crate reuses a stale `target/incremental`. Also seen with `sccache`/`cargo-cache` mis-keying, after `git checkout`/`git rebase` across a commit that removed defs, or when a workspace member is removed from `Cargo.toml` but `target/` is retained.","solutions":["Delete the incremental cache and rebuild: `rm -rf target/<triple>/incremental target/debug/incremental` then `cargo build`.","Run `cargo clean` (full) if a per-crate clean isn't enough.","After deleting/renaming public items in a library, run `cargo clean -p <library>` before rebuilding dependents.","If a CI layer caches `target/`, key it on the source hash of every upstream crate the build links, not just the leaf.","Disable incremental compilation as a stopgap: `CARGO_INCREMENTAL=0`.","If reproducible after a full clean, report to rust-lang/rust with `rustc -vV`, the `DefPathHash`, and both crate versions."],"exampleFix":"# before\n$ rm src/old_module.rs        # remove an item another crate cached a DefId for\n$ cargo build                 # panic: Failed to convert DefPathHash {...}\n\n# after\n$ cargo clean -p downstream-crate\n$ cargo build                 # recomputes query results against the new def table","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// DefPathHash conversion fails when the encoded crate identity no longer matches\n// the current DefPathHash map (e.g. dep graph changed under a reused cache).\nuse std::process::Command;\nfn build_robust(dir: &str) -> std::io::Result<std::process::ExitStatus> {\n    let s = Command::new(\"cargo\").args([\"build\"]).current_dir(dir).status()?;\n    if s.success() { return Ok(s); }\n    // Drop the dep-graph / incremental artifacts, then fall back to a non-incremental build.\n    let _ = Command::new(\"cargo\").args([\"clean\"]).current_dir(dir).status();\n    Command::new(\"cargo\").env(\"CARGO_INCREMENTAL\", \"0\").arg(\"build\").current_dir(dir).status()\n}","preventionTips":["Clean after adding/removing crates from the workspace — DefPathHashes are stable only per crate-graph.","Keep proc-macro crate versions in lockstep across the graph; re-exports shift DefPathHash mapping.","Pin dependencies (Cargo.lock) so dependent identity hashes do not drift.","Avoid `cargo` builds that mix `--features` toggles against the same `target/` without a clean."],"tags":["rustc","incremental-compilation","on-disk-cache","def-path-hash","cache-corruption"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}