atuinsh/atuin · error

Could not find history directory

Error message

Could not find history directory {:?}. Try setting and exporting $HISTFILE

What it means

`is_dir` (atuin-client/src/import/mod.rs) validates that a given path is a directory during import (used for directory-style history stores, e.g. fish or some zsh setups); otherwise it bails with "Could not find history directory ... Try setting and exporting $HISTFILE". Despite the message mentioning $HISTFILE, the failing input is a directory path.

Solutions

  1. Create/verify the expected history directory (launch the shell once, or `mkdir -p` it)
  2. Export HISTFILE (or the shell-specific variable) to the correct location before importing
  3. Check that the path in the message exists and is a directory with `ls -la`
  4. Ensure you run the import as the user who owns the shell history

Example fix

// before
atuin import fish
// error: Could not find history directory "..."
// after
mkdir -p ~/.local/share/fish && fish -c 'exit' && atuin import fish
Defensive patterns

Strategy: validation

Validate before calling

// check before import (directory-based history)
let dir = shell_history_dir(); // e.g. ~/.local/share/fish
if !dir.is_dir() {
    eprintln!("history directory {} missing; launch the shell once or mkdir -p it", dir.display());
}

Type guard

fn is_existing_dir(p: &std::path::Path) -> bool { p.is_dir() }

Try / catch

match import_history().await {
    Err(e) if e.to_string().contains("Could not find history directory") => {
        eprintln!("Create the expected history directory or fix HISTFILE and retry");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running an import for a shell whose history lives in a directory (e.g. fish's `fish_history` layout or directory-based history) when that directory does not exist or the resolved path points to something else.

Common situations: Fish never launched so its history directory was never created; HISTFILE/derived path misconfigured to a file when a directory is expected; running import under a different user/home than the one that owns the history.

Related errors


AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19). Data as JSON: /api/errors/6b2e3fda76fd1b84. Report an issue: GitHub.

Appendix: source

Thrown at crates/atuin-client/src/import/mod.rs:114

fn read_to_end(path: PathBuf) -> Result<Vec<u8>> {
    let mut bytes = Vec::new();
    let mut f = File::open(path)?;
    f.read_to_end(&mut bytes)?;
    Ok(bytes)
}
fn is_file(p: PathBuf) -> Result<PathBuf> {
    if p.is_file() {
        Ok(p)
    } else {
        bail!("Could not find history file {:?}. Try setting and exporting $HISTFILE", p);
    }
}
fn is_dir(p: PathBuf) -> Result<PathBuf> {
    if p.is_dir() {
        Ok(p)
    } else {
        bail!("Could not find history directory {:?}. Try setting and exporting $HISTFILE", p);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[derive(Default)]
    pub struct TestLoader {
        pub buf: Vec<History>,
    }

    #[async_trait]
    impl Loader for TestLoader {
        async fn push(&mut self, hist: History) -> Result<()> {
            self.buf.push(hist);
            Ok(())
        }

View on GitHub (pinned to 900007c480)