{"id":"31bce38ae2426a58","repo":"rust-lang/rust","slug":"invalid-tag-for-clearcrosscrate-tag","errorCode":null,"errorMessage":"Invalid tag for ClearCrossCrate: {tag:?}","messagePattern":"Invalid tag for ClearCrossCrate: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_middle/src/mir/mod.rs","lineNumber":831,"sourceCode":"        }\n    }\n}\nimpl<'tcx, D: TyDecoder<'tcx>, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {\n    #[inline]\n    fn decode(d: &mut D) -> ClearCrossCrate<T> {\n        if D::CLEAR_CROSS_CRATE {\n            return ClearCrossCrate::Clear;\n        }\n\n        let discr = u8::decode(d);\n\n        match discr {\n            TAG_CLEAR_CROSS_CRATE_CLEAR => ClearCrossCrate::Clear,\n            TAG_CLEAR_CROSS_CRATE_SET => {\n                let val = T::decode(d);\n                ClearCrossCrate::Set(val)\n            }\n            tag => panic!(\"Invalid tag for ClearCrossCrate: {tag:?}\"),\n        }\n    }\n}\n\n/// Grouped information about the source code origin of a MIR entity.\n/// Intended to be inspected by diagnostics and debuginfo.\n/// Most passes can work with it as a whole, within a single function.\n// The unofficial Cranelift backend, at least as of #65828, needs `SourceInfo` to implement `Eq` and\n// `Hash`. Please ping @bjorn3 if removing them.\n#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, StableHash)]\npub struct SourceInfo {\n    /// The source span for the AST pertaining to this MIR entity.\n    pub span: Span,\n\n    /// The source scope, keeping track of which bindings can be\n    /// seen by debuginfo, active lint levels, etc.\n    pub scope: SourceScope,\n}","sourceCodeStart":813,"sourceCodeEnd":849,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_middle/src/mir/mod.rs#L813-L849","documentation":"Panic in `ClearCrossCrate<T>::decode` when decoding an incremental-compilation / cross-crate query result: the discriminant byte read from the on-disk cache is neither TAG_CLEAR_CROSS_CRATE_CLEAR (0) nor TAG_CLEAR_CROSS_CRATE_SET (1). rustc_middle throws it because the encoded stream's tag enum is closed and an unknown byte can only mean a corrupted cache or a decoder/encoder version mismatch.","triggerScenarios":"Triggered when rustc deserializes a `ClearCrossCrate<T>` from the incremental/incremental-compilation cache or an rmeta/crate-metadata stream whose first byte after the CLEAR_CROSS_CRATE gating check is not 0 or 1. Reproducible by manually truncating or patching a cached object, or by loading an rmeta written by a different compiler build whose encoder changed the tag layout.","commonSituations":"Stale or partially-written incremental cache after a SIGKILL/OOM or disk-full during a prior build; switching between compiler nightlies without clearing `target/`; mismatched rustc driver / custom backend that re-encodes `ClearCrossCrate` with a non-canonical tag; rlib/rmeta produced by an experimental toolchain being consumed by another.","solutions":["Delete the incremental cache and build artifacts: `cargo clean` (or remove `target/debug/incremental`), then rebuild.","Ensure every crate in the dependency graph is compiled by the same rustc commit/nightly; re-compile dependencies from source rather than mixing rmeta from different toolchains.","If using a custom rustc driver or backend that touches `ClearCrossCrate` encoding, verify it only ever writes TAG_CLEAR_CROSS_CRATE_CLEAR or TAG_CLEAR_CROSS_CRATE_SET and bump the cache schema/version when the encoding changes.","Report a bug to rustc with the panic backtrace and the exact rustc commit if the corruption recurs on a clean cache with a single consistent toolchain."],"exampleFix":"# before (stale cache corrupts decode)\ncargo build\n# thread 'rustc' panicked at compiler/rustc_middle/src/mir/mod.rs:831: Invalid tag for ClearCrossCrate: ...\n\n# after\ncargo clean && cargo build","handlingStrategy":"fallback","validationCode":"// No pre-call validation is possible: the discriminant tag is an opaque\n// byte inside the already-encoded rmeta/incremental stream.\n// The only reliable recovery is to discard the corrupted artifact.\nfn artifact_is_likely_stale(crate_stamp: std::time::SystemTime, src_stamp: std::time::SystemTime) -> bool {\n    crate_stamp < src_stamp // cached object predates its source\n}","typeGuard":null,"tryCatchPattern":"// ClearCrossCrate::decode panics on an unknown tag (stream corruption).\n// Wrap the decode and, on panic, fall back to a clean rebuild.\nuse std::panic::{catch_unwind, AssertUnwindSafe};\nlet decoded = catch_unwind(AssertUnwindSafe(|| {\n    // <T as Decodable>::decode(&mut decoder_for_clearcrosscrate)\n    decode_clearcrosscrate::<T>(&mut d)\n}));\nmatch decoded {\n    Ok(value) => value,\n    Err(_payload) => {\n        // incremental / rmeta stream was corrupt -> purge and rebuild\n        let _ = std::fs::remove_dir_all(\"target/debug/incremental\");\n        let _ = std::fs::remove_file(offending_rmeta_path);\n        // re-run the build without --incremental for this crate\n        panic_not_a_user_error_but_rebuild_initiated();\n    }\n}","preventionTips":["Treat this panic as data corruption: it fires only when decoding cross-crate MIR cached by a prior, possibly-incompatible compiler build.","Never mix artifacts between rustc versions or between incremental sessions; run `cargo clean` (or remove target/debug/incremental) after a toolchain update.","Avoid aborting a build midway (kill -9, OOM, power loss) which can leave half-written rmeta/incremental blobs that decode to invalid tags.","If you persist or transfer rmeta/incremental caches, checksum them; reject and regenerate on mismatch instead of feeding bad bytes to the decoder."],"tags":["rustc","incremental-compilation","deserialization","cache-corruption"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}