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
- Create/verify the expected history directory (launch the shell once, or `mkdir -p` it)
- Export HISTFILE (or the shell-specific variable) to the correct location before importing
- Check that the path in the message exists and is a directory with `ls -la`
- 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
- Run the shell at least once so it creates its history directory
- Import as the user who owns the shell history
- Confirm the path in the error is a directory, not a file
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
- Could not find history file
- Could not find history directory
- Could not find history file
- default socket path always has a parent
- key file vanished immediately after a concurrent write
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)