jdx/mise · error
[bootstrap.macos.dock].apps: expected an absolute or ~/…
Error message
[bootstrap.macos.dock].apps: expected an absolute or ~/ application path: {value} What it means
Thrown by dock::paths when a [bootstrap.macos.dock].apps entry fails the application-path validation. A valid entry must be an absolute path, end in a .app extension (case-insensitive), contain no parent-directory (..) components, and contain no NUL bytes. Anything else — relative paths, non-.app files, traversal attempts — is rejected.
Solutions
- Make the path absolute, e.g. /Applications/Foo.app or ~/Applications/Foo.app
- Ensure the path points to a .app bundle (correct extension)
- Remove any ".." components from the path
- Sanitize any dynamic input feeding the apps array
Example fix
// before apps = ["Applications/MyApp"] // after apps = ["/Applications/MyApp.app"]
Defensive patterns
Strategy: validation
Validate before calling
fn validate_app_path(value: &str) -> Result<(), String> {
let p = Path::new(value);
let ok = p.is_absolute()
&& p.extension().map_or(false, |e| e.eq_ignore_ascii_case("app"))
&& !p.components().any(|c| matches!(c, std::path::Component::ParentDir))
&& !value.contains('\0');
if !ok { return Err(format!("invalid app path: {value}")); }
Ok(())
} Type guard
fn is_valid_app_path(value: &str) -> bool {
let p = Path::new(value);
p.is_absolute()
&& p.extension().map_or(false, |e| e.eq_ignore_ascii_case("app"))
&& !p.components().any(|c| matches!(c, std::path::Component::ParentDir))
&& !value.contains('\0')
} Prevention
- Always list full absolute paths ending in .app
- Never build app paths from untrusted input (traversal risk)
- Normalize paths before writing them into config
When it happens
Trigger: dock.apps entries like "Applications/Foo.app" (relative), "/Applications/Foo" (missing .app), "/opt/../Applications/Foo.app" (parent dir), or paths containing a NUL character.
Common situations: Forgetting the .app extension; using paths relative to the config file; typos introducing ".."; untrusted input injected into the apps list (path traversal attempt).
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- [bootstrap.macos.dock].apps: expected a path relative to…
- duplicate Dock application
- [bootstrap.macos.dock].apps: expected an array of…
- com.apple.dock persistent-apps is not an array; left…
- defaults patch path must not be empty
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/e4ac1b3f6b926e10.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/defaults/dock.rs:26
let DefaultsValue::Array(values) = value else {
eyre::bail!("[bootstrap.macos.dock].apps: expected an array of application paths");
};
let mut paths = Vec::new();
let mut seen = std::collections::HashSet::new();
for value in values {
let DefaultsValue::Str(value) = value else {
eyre::bail!("[bootstrap.macos.dock].apps: expected an array of application paths");
};
let path = if let Some(rest) = value.strip_prefix("~/") {
eyre::ensure!(
!Path::new(rest).has_root(),
"[bootstrap.macos.dock].apps: expected a path relative to home: {value}"
);
crate::env::HOME.join(rest)
} else {
PathBuf::from(value)
};
eyre::ensure!(
path.is_absolute()
&& path
.extension()
.is_some_and(|ext| ext.eq_ignore_ascii_case("app"))
&& !path.components().any(|c| matches!(c, Component::ParentDir))
&& !value.contains('\0'),
"[bootstrap.macos.dock].apps: expected an absolute or ~/ application path: {value}"
);
let path: PathBuf = path.components().collect();
eyre::ensure!(
seen.insert(crate::file::canonicalize_or_self(&path)),
"duplicate Dock application: {}",
path.display()
);
paths.push(path);
}
Ok(paths)
}View on GitHub (pinned to 533346cc37)