Skip to content

Commit 445df7e

Browse files
fix(config-dir): Resolve relative TURBO_CONFIG_DIR_PATH before validation (#11122)
fix(config-dir): resolve relative TURBO_CONFIG_DIR_PATH before validation Fixes issue **#8645** ### Summary This PR fixes a bug where setting `TURBO_CONFIG_DIR_PATH` to a *relative* path (e.g., `"configs"`) caused Turborepo to fail with: PathError::NotAbsolute("configs") `AbsoluteSystemPathBuf::new()` only accepts absolute paths, but the value from the environment variable was passed directly without being resolved. This caused a startup failure even though the provided path was valid. ### Root Cause When a user sets: TURBO_CONFIG_DIR_PATH="configs" Turborepo attempted to validate `"configs"` as an absolute path. Since it is relative, the validator rejected it, causing Turborepo to stop early. ### What This PR Changes - Detects whether the provided `TURBO_CONFIG_DIR_PATH` is **relative** - If relative, resolves it against the current working directory: ```rust std::env::current_dir()?.join(raw) Converts the resolved path to UTF-8 Passes the resulting absolute path into AbsoluteSystemPathBuf::new() Leaves absolute paths fully unchanged Introduces zero breaking changes Why This Fix Is Safe - Relative → absolute resolution is deterministic and standard practice - Absolute paths behave exactly the same as before - Error surface area decreases (fewer startup failures) - The change is minimal, well-scoped, and consistent with existing path logic - No impact on users who do not set the environment variable --------- Co-authored-by: Anthony Shew <[email protected]> Co-authored-by: Anthony Shew <[email protected]>
1 parent 5e1e566 commit 445df7e

File tree

1 file changed

+29
-4
lines changed
  • crates/turborepo-dirs/src

1 file changed

+29
-4
lines changed

crates/turborepo-dirs/src/lib.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,23 @@ use turbopath::{AbsoluteSystemPathBuf, PathError};
1313
/// is set, it will return that path instead of `dirs_next::config_dir`.
1414
pub fn config_dir() -> Result<Option<AbsoluteSystemPathBuf>, PathError> {
1515
if let Ok(dir) = std::env::var("TURBO_CONFIG_DIR_PATH") {
16-
return AbsoluteSystemPathBuf::new(dir).map(Some);
16+
// Reject empty strings per Unix convention
17+
if dir.is_empty() {
18+
return Err(PathError::InvalidUnicode(dir));
19+
}
20+
21+
let raw = std::path::PathBuf::from(&dir);
22+
23+
// Resolve to absolute path if necessary
24+
let abs = if raw.is_absolute() {
25+
raw
26+
} else {
27+
std::env::current_dir()?.join(raw)
28+
};
29+
30+
let abs_str = abs.to_str().ok_or(PathError::InvalidUnicode(dir))?;
31+
32+
return AbsoluteSystemPathBuf::new(abs_str).map(Some);
1733
}
1834

1935
dirs_config_dir()
@@ -28,6 +44,11 @@ pub fn config_dir() -> Result<Option<AbsoluteSystemPathBuf>, PathError> {
2844
/// is set, it will return that path instead of `dirs_next::config_dir`.
2945
pub fn vercel_config_dir() -> Result<Option<AbsoluteSystemPathBuf>, PathError> {
3046
if let Ok(dir) = std::env::var("VERCEL_CONFIG_DIR_PATH") {
47+
// Reject empty strings per Unix convention.
48+
if dir.is_empty() {
49+
return Err(PathError::InvalidUnicode(dir));
50+
}
51+
3152
return AbsoluteSystemPathBuf::new(dir).map(Some);
3253
}
3354

@@ -73,14 +94,18 @@ mod tests {
7394
}
7495

7596
#[test]
76-
fn test_config_dir_with_invalid_env_var() {
77-
// Set TURBO_CONFIG_DIR_PATH to a relative path (invalid)
97+
fn test_config_dir_with_relative_path() {
98+
// Set TURBO_CONFIG_DIR_PATH to a relative path (should be resolved to absolute)
7899
unsafe {
79100
env::set_var("TURBO_CONFIG_DIR_PATH", "relative/path");
80101
}
81102

82103
let result = config_dir();
83-
assert!(result.is_err());
104+
assert!(result.is_ok());
105+
let path = result.unwrap();
106+
assert!(path.is_some());
107+
// Verify it was resolved to an absolute path
108+
assert!(path.unwrap().as_path().is_absolute());
84109

85110
unsafe {
86111
env::remove_var("TURBO_CONFIG_DIR_PATH");

0 commit comments

Comments
 (0)