{"record":{"id":"a4462c856deaa537","repo":"vercel/turborepo","slug":"failed-to-calculate-turbo-hash-err","errorCode":null,"errorMessage":"failed to calculate Turbo hash: {err}","messagePattern":"failed to calculate Turbo hash: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/turborepo-hash/src/traits.rs","lineNumber":30,"sourceCode":"    fn try_hash(self) -> Result<String, Error> {\n        let message = self.into_builder()?;\n\n        debug_assert_eq!(\n            message.get_segments_for_output().len(),\n            1,\n            \"message is not canonical\"\n        );\n\n        let buf = message.get_segments_for_output()[0];\n\n        let out = xxhash_rust::xxh64::xxh64(buf, 0);\n\n        Ok(hex::encode(out.to_be_bytes()))\n    }\n\n    fn hash(self) -> String {\n        self.try_hash()\n            .unwrap_or_else(|err| panic!(\"failed to calculate Turbo hash: {err}\"))\n    }\n}\n","sourceCodeStart":12,"sourceCodeEnd":33,"githubUrl":"https://github.com/vercel/turborepo/blob/f9245100cf0d31d96628804ead485f6bf226e55a/crates/turborepo-hash/src/traits.rs#L12-L33","documentation":"turborepo-hash implements a capnproto-based Hashable trait: try_hash serializes the message and xxh64-hashes its first segment, returning an error when the capnp \"message is not canonical\". The convenience hash() converts any such error into a panic (\"failed to calculate Turbo hash\"), so this is an internal invariant failure inside turbo's task hashing, not a caller-configurable condition.","triggerScenarios":"Hashing inputs whose capnp serialization is non-canonical — an internal API misuse or a serialization bug in the caller building the message; effectively unreachable from JavaScript/TypeScript surfaces, it aborts the turbo process.","commonSituations":"Seen inside `turbo run` after upgrading across serialization changes, with unusual workspace/task configurations, or with corrupted in-memory state; never triggered by config files alone.","solutions":["Upgrade turborepo — known serialization bugs are fixed in patches","Clear the local turbo cache and .turbo directories, then retry","If it reproduces, minimize the turbo.json/workspace setup and file an issue","In downstream Rust code, call try_hash() instead of hash() to get a Result"],"exampleFix":"// before\nlet hash = item.hash(); // panics on non-canonical message\n// after\nmatch item.try_hash() {\n    Ok(hash) => { /* use hash */ }\n    Err(err) => { /* degrade gracefully: skip caching, log */ }\n}","handlingStrategy":"fallback","validationCode":"// Prefer the Result-returning API in downstream Rust code\nmatch hashable.try_hash() {\n    Ok(h) => use_hash(h),\n    Err(e) => {\n        tracing::warn!(\"hash failed, skipping cache: {e}\");\n        return None;\n    }\n}","typeGuard":null,"tryCatchPattern":"std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| item.hash()))\n    .map_err(|p| {\n        let msg = p\n            .downcast_ref::<&str>()\n            .map(|s| s.to_string())\n            .unwrap_or_else(|| \"hash panic\".into());\n        msg\n    })\n    .and_then(|h| Ok(h))","preventionTips":["Pin a known-good turborepo version; upgrade deliberately rather than floating","Keep hashing inside the turbo process boundary so a panic cannot take down your host application","In Rust code, never call hash() on untrusted/unvalidated Hashable inputs — use try_hash()"],"tags":["rust","panic","hashing","capnproto"],"backgroundTag":"rust-panic-invariant-violation","analyzedSha":"f9245100cf0d31d96628804ead485f6bf226e55a","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}