nikivdev/code · error
unhash failed: {} {}{}
Error message
unhash failed: {}
{}{} What it means
`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.
Source
Thrown at src/hash.rs:33
}
let unhash_bin = which::which("unhash")
.context("unhash not found on PATH. Run `f deploy-unhash` in the unhash repo.")?;
let mut cmd = Command::new(unhash_bin);
cmd.args(&opts.args);
if env::var("UNHASH_KEY").is_err() {
if let Ok(Some(value)) = flow_env::get_personal_env_var("UNHASH_KEY") {
cmd.env("UNHASH_KEY", value);
}
}
let output = cmd.output().context("failed to run unhash")?;
if !output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("unhash failed: {}\n{}{}", output.status, stdout, stderr);
}
let stdout = String::from_utf8_lossy(&output.stdout);
let mut lines = stdout.lines().filter(|line| !line.trim().is_empty());
let hash = lines
.next()
.ok_or_else(|| anyhow::anyhow!("unhash output missing hash"))?
.trim()
.to_string();
let link = format!("{LINK_PREFIX}{hash}");
copy_to_clipboard(&link)?;
println!("{hash}");
println!("{link}");
if let Some(path_line) = lines.next() {
println!("{}", path_line.trim());View on GitHub (pinned to a747e741ae)
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
Example fix
# before (opaque invocation) f hash "unstash./abc123" # after (inspect actual args/path first) ls -l <path> && unhash <path> # reproduce directly, then fix the path or entry
Defensive patterns
Strategy: try-catch
Validate before calling
let unhash = which::which("unhash")?;
for p in &paths {
anyhow::ensure!(p.exists(), "path does not exist: {}", p.display());
anyhow::ensure!(p.is_readable(), "path not readable: {}", p.display());
} Type guard
null
Try / catch
match hash::run(opts) {
Err(e) if e.to_string().starts_with("unhash failed:") => {
// stderr/stdout of unhash are embedded; forward them verbatim
eprintln!("{e}");
std::process::exit(1);
}
r => r?,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- hive not found on PATH. Install from https://github.com/exam
- hive agent '{}' exited with status {:?}
- codex skill-eval launchd install failed: {}
- enable-global is only supported for Codex sessions; use `f c
- Project mismatch. Bundle is for '{}' but this repo is '{}'.
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/50df69fe4bac0374.
Report an issue: GitHub.