{"record":{"id":"6b2e3fda76fd1b84","repo":"atuinsh/atuin","slug":"could-not-find-history-directory-try-setting","errorCode":null,"errorMessage":"Could not find history directory {:?}. Try setting and exporting $HISTFILE","messagePattern":"Could not find history directory (.+?)\\. Try setting and exporting \\$HISTFILE","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin-client/src/import/mod.rs","lineNumber":114,"sourceCode":"\nfn read_to_end(path: PathBuf) -> Result<Vec<u8>> {\n    let mut bytes = Vec::new();\n    let mut f = File::open(path)?;\n    f.read_to_end(&mut bytes)?;\n    Ok(bytes)\n}\nfn is_file(p: PathBuf) -> Result<PathBuf> {\n    if p.is_file() {\n        Ok(p)\n    } else {\n        bail!(\"Could not find history file {:?}. Try setting and exporting $HISTFILE\", p);\n    }\n}\nfn is_dir(p: PathBuf) -> Result<PathBuf> {\n    if p.is_dir() {\n        Ok(p)\n    } else {\n        bail!(\"Could not find history directory {:?}. Try setting and exporting $HISTFILE\", p);\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[derive(Default)]\n    pub struct TestLoader {\n        pub buf: Vec<History>,\n    }\n\n    #[async_trait]\n    impl Loader for TestLoader {\n        async fn push(&mut self, hist: History) -> Result<()> {\n            self.buf.push(hist);\n            Ok(())\n        }","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/atuinsh/atuin/blob/900007c48045867e7f44b0f9bc55ad9dbe99ee0d/crates/atuin-client/src/import/mod.rs#L96-L132","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\natuin import fish\n// error: Could not find history directory \"...\"\n// after\nmkdir -p ~/.local/share/fish && fish -c 'exit' && atuin import fish","handlingStrategy":"validation","validationCode":"// check before import (directory-based history)\nlet dir = shell_history_dir(); // e.g. ~/.local/share/fish\nif !dir.is_dir() {\n    eprintln!(\"history directory {} missing; launch the shell once or mkdir -p it\", dir.display());\n}","typeGuard":"fn is_existing_dir(p: &std::path::Path) -> bool { p.is_dir() }","tryCatchPattern":"match import_history().await {\n    Err(e) if e.to_string().contains(\"Could not find history directory\") => {\n        eprintln!(\"Create the expected history directory or fix HISTFILE and retry\");\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["import","filesystem","shell-history"],"backgroundTag":"directory-not-found","analyzedSha":"900007c48045867e7f44b0f9bc55ad9dbe99ee0d","analyzedAt":"2026-09-19T12:52:51.491Z","contentChangedAt":"2026-09-19T12:52:51.491Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}