{"record":{"id":"50df69fe4bac0374","repo":"nikivdev/code","slug":"unhash-failed","errorCode":null,"errorMessage":"unhash failed: {}\n{}{}","messagePattern":"unhash failed: (.+?)\n(.+?)(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/hash.rs","lineNumber":33,"sourceCode":"    }\n\n    let unhash_bin = which::which(\"unhash\")\n        .context(\"unhash not found on PATH. Run `f deploy-unhash` in the unhash repo.\")?;\n\n    let mut cmd = Command::new(unhash_bin);\n    cmd.args(&opts.args);\n\n    if env::var(\"UNHASH_KEY\").is_err() {\n        if let Ok(Some(value)) = flow_env::get_personal_env_var(\"UNHASH_KEY\") {\n            cmd.env(\"UNHASH_KEY\", value);\n        }\n    }\n\n    let output = cmd.output().context(\"failed to run unhash\")?;\n    if !output.status.success() {\n        let stdout = String::from_utf8_lossy(&output.stdout);\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        bail!(\"unhash failed: {}\\n{}{}\", output.status, stdout, stderr);\n    }\n\n    let stdout = String::from_utf8_lossy(&output.stdout);\n    let mut lines = stdout.lines().filter(|line| !line.trim().is_empty());\n    let hash = lines\n        .next()\n        .ok_or_else(|| anyhow::anyhow!(\"unhash output missing hash\"))?\n        .trim()\n        .to_string();\n\n    let link = format!(\"{LINK_PREFIX}{hash}\");\n    copy_to_clipboard(&link)?;\n\n    println!(\"{hash}\");\n    println!(\"{link}\");\n\n    if let Some(path_line) = lines.next() {\n        println!(\"{}\", path_line.trim());","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/hash.rs#L15-L51","documentation":"`f hash` delegates to the external `unhash` binary. If `unhash` exits with a non-zero status, the command bails with this message, embedding the exit status plus unhash's stdout and stderr so the underlying failure is visible. This is the error path for any failure inside unhash itself, not for the wrapper's own setup.","triggerScenarios":"unhash encountering a missing/permission-denied input path; unhash failing to parse its arguments as forwarded by the wrapper; unhash's own internal errors (corrupt hash DB, network backend failure for unstash operations); disk full while unhash writes output.","commonSituations":"Hashing a path that was deleted or renamed between listing and hashing; passing flags unhash doesn't recognize; unhash's data directory corrupted or not initialized; `unstash./` arguments referencing entries that don't exist.","solutions":["Read the stdout/stderr embedded in the error message — it contains unhash's own diagnosis","Verify the target paths exist and are readable before hashing","Run `unhash` directly with the same arguments to reproduce outside the wrapper","Reinstall or update unhash: `f deploy-unhash` in the unhash repo"],"exampleFix":"# before (opaque invocation)\n f hash \"unstash./abc123\"\n# after (inspect actual args/path first)\nls -l <path> && unhash <path>   # reproduce directly, then fix the path or entry","handlingStrategy":"try-catch","validationCode":"let unhash = which::which(\"unhash\")?;\nfor p in &paths {\n    anyhow::ensure!(p.exists(), \"path does not exist: {}\", p.display());\n    anyhow::ensure!(p.is_readable(), \"path not readable: {}\", p.display());\n}","typeGuard":"null","tryCatchPattern":"match hash::run(opts) {\n    Err(e) if e.to_string().starts_with(\"unhash failed:\") => {\n        // stderr/stdout of unhash are embedded; forward them verbatim\n        eprintln!(\"{e}\");\n        std::process::exit(1);\n    }\n    r => r?,\n}","preventionTips":["Verify all target paths exist before invoking f hash","Keep unhash installed and up to date (`f deploy-unhash`)","Run unhash directly when debugging to see its native errors","Avoid passing flags through the wrapper that unhash may not support"],"tags":["subprocess","external-binary","cli","rust"],"backgroundTag":"external-command-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}