a-b-street/abstreet · error
Can't find the data/ directory
Error message
Can't find the data/ directory
What it means
abstio::path resolves non-player paths by locating the repo's data/ directory: it checks ABST_DATA_DIR (compile time), wasm, then data/, ../data/, ../../data/, ../../../data/ relative to the current working directory. If none of these exists when the path root is first initialized, it panics with 'Can't find the data/ directory'. This is the player/-branch variant (ROOT_PLAYER_DIR), i.e. it fires while resolving a 'player/...' path.
Solutions
- Run the binary from a directory where data/ exists (the repo root) or within 3 levels of it (so ../data, ../../data, or ../../../data resolves)
- Rebuild with ABST_DATA_DIR set to the absolute path of the data directory: ABST_DATA_DIR=/path/to/abstreet/data cargo build --release
- Clone/sync the data directory (e.g. ./import.sh or downloading data from the project) next to where the binary runs
- Patch ROOT_PLAYER_DIR resolution to accept an explicit runtime override (env var read at runtime instead of option_env!)
Example fix
// before ./target/release/abstreet # run from ~/, no data/ nearby -> panic // after cd /path/to/abstreet && ./target/release/abstreet # or: ABST_DATA_DIR=/path/to/abstreet/data cargo build --release
Defensive patterns
Strategy: validation
Validate before calling
fn data_dir_locatable() -> bool {
["data/", "../data/", "../../data/", "../../../data/"]
.iter()
.any(|p| std::path::Path::new(p).is_dir())
|| std::env::var_os("ABST_DATA_DIR").is_some()
} Type guard
fn can_resolve_abstio_paths() -> bool {
cfg!(target_arch = "wasm32")
|| std::env::var_os("ABST_DATA_DIR").is_some()
|| data_dir_locatable()
} Try / catch
let ok = std::panic::catch_unwind(|| abstio::path("system/us/seattle/maps/montlake.bin"));
if ok.is_err() {
eprintln!("Run from the repo root (or set ABST_DATA_DIR at build time)");
} Prevention
- Run A/B Street binaries and tests from the repository root or within 3 levels of it
- Keep the data/ directory next to where you execute the binary
- Set ABST_DATA_DIR at build time for fixed-location installs
- Check that data/ exists in CI before invoking tools that use abstio::path
When it happens
Trigger: First call to abstio::path (or path_player/path_edits/path_save etc.) with a 'player/'-prefixed path, from a working directory where none of data/, ../data/, ../../data/, ../../../data/ exists and the binary was not compiled with ABST_DATA_DIR set (or not on wasm32). The OnceLock caches the failure on the first call.
Common situations: Running a compiled A/B Street binary outside the repository checkout (e.g. copying the executable elsewhere), running tests/crates from a directory above or beside the repo, CI jobs that don't clone data/, or builds without ABST_DATA_DIR set while packaged.
Related errors
- Your current directory doesn't have the data/ directory…
- This build of A/B Street stores player data in…
- CityName::new( , ) has a country code that isn't two letters
- Couldn't read_json( )
- Couldn't read_binary
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/f86f41344843b931.
Report an issue: GitHub.
Appendix: source
Thrown at abstio/src/abst_paths.rs:41
// If you're packaging for a release and want the player's local data directory to be
// $HOME/.abstreet, set ABST_PLAYER_HOME_DIR=1
if option_env!("ABST_PLAYER_HOME_DIR").is_some() {
match std::env::var("HOME") {
Ok(dir) => format!("{}/.abstreet", dir.trim_end_matches('/')),
Err(err) => panic!("This build of A/B Street stores player data in $HOME/.abstreet, but $HOME isn't set: {}", err),
}
} else if cfg!(target_arch = "wasm32") {
"../data".to_string()
} else if file_exists("data/".to_string()) {
"data".to_string()
} else if file_exists("../data/".to_string()) {
"../data".to_string()
} else if file_exists("../../data/".to_string()) {
"../../data".to_string()
} else if file_exists("../../../data/".to_string()) {
"../../../data".to_string()
} else {
panic!("Can't find the data/ directory");
}
});
format!("{dir}/{p}")
} else {
let dir = ROOT_DIR.get_or_init(|| {
// If you're packaging for a release and need the data directory to be in some fixed
// location: ABST_DATA_DIR=/some/path cargo build ...
if let Some(dir) = option_env!("ABST_DATA_DIR") {
dir.trim_end_matches('/').to_string()
} else if cfg!(target_arch = "wasm32") {
"../data".to_string()
} else if file_exists("data/".to_string()) {
"data".to_string()
} else if file_exists("../data/".to_string()) {
"../data".to_string()
} else if file_exists("../../data/".to_string()) {
"../../data".to_string()
} else if file_exists("../../../data/".to_string()) {View on GitHub (pinned to 0964f29315)