rtk-ai/rtk · error
no local data directory available
Error message
no local data directory available
What it means
retriever::db_path builds the on-disk path of the recall SQLite database by starting from the platform's local data directory (dirs::data_local_dir()). On platforms where that directory cannot be determined, it returns this error instead of guessing a path.
Solutions
- Set the HOME environment variable to a writable directory (e.g. export HOME=/root in containers).
- Set XDG_DATA_HOME to an existing writable path so dirs can resolve the data dir.
- Run rtk from an environment with a normal user profile rather than an empty env.
Example fix
// before (Dockerfile) CMD ["rtk", "gain"] // after ENV HOME=/root CMD ["rtk", "gain"]
Defensive patterns
Strategy: validation
Validate before calling
import os, sys
if not (os.environ.get('HOME') or os.environ.get('XDG_DATA_HOME')):
sys.exit('Set HOME or XDG_DATA_HOME before running rtk') Try / catch
match rtk_gain() {
Err(e) if e.to_string().contains("no local data directory") => {
std::env::set_var("HOME", "/tmp");
retry()
}
other => other,
} Prevention
- Always set HOME in Docker/CI images
- Set XDG_DATA_HOME explicitly in minimal environments
- Avoid running rtk from services with an empty environment
When it happens
Trigger: Calling open/open_existing/with_open when dirs::data_local_dir() returns None — typically when $XDG_DATA_HOME and $HOME are both unset, or on exotic environments (minimal containers, setuid contexts, some CI images) with no resolvable home directory.
Common situations: Running rtk in a Docker container without HOME set; stripped-down CI runners; cron/systemd services with an empty environment; Windows profiles without a LOCALAPPDATA equivalent.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- ambiguous hash prefix
- Failed to query first seen timestamp
- tree command not found. Install it first: - macOS: brew…
AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19).
Data as JSON: /api/errors/130a8da4b0798544.
Report an issue: GitHub.
Appendix: source
Thrown at src/core/retriever.rs:184
.read_to_end(&mut out)
.context("gunzip")?;
Ok(out)
}
fn db_path(cfg: &RetrieverConfig) -> Result<PathBuf> {
if let Ok(p) = std::env::var("RTK_RECALL_DB") {
return Ok(PathBuf::from(p));
}
if let Some(ref p) = cfg.database_path {
return Ok(p.clone());
}
// A test that names no store must never reach the developer's own: its rows
// would ship as real usage through the telemetry ping.
#[cfg(test)]
let base = std::env::temp_dir().join(format!("rtk-test-store-{}", std::process::id()));
#[cfg(not(test))]
let base = dirs::data_local_dir()
.ok_or_else(|| anyhow::anyhow!("no local data directory available"))?
.join(super::constants::RTK_DATA_DIR);
Ok(base.join(RECALL_DB))
}
fn open(cfg: &RetrieverConfig) -> Result<Connection> {
let path = db_path(cfg)?;
if let Some(parent) = path.parent() {
let _ = crate::core::utils::create_private_dir(parent);
}
crate::core::utils::open_private(std::fs::OpenOptions::new().write(true).create(true), &path)
.with_context(|| format!("pre-create private recall DB: {}", path.display()))?;
let conn = Connection::open(&path).with_context(|| format!("open {}", path.display()))?;
// best-effort: NFS / read-only filesystems may reject WAL
let _ = conn.execute_batch("PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000;");
init_schema(&conn)?;
Ok(conn)
}
View on GitHub (pinned to 0924356b4c)