{"record":{"id":"e4ac1b3f6b926e10","repo":"jdx/mise","slug":"bootstrap-macos-dock-apps-expected-an-absolute-or","errorCode":null,"errorMessage":"[bootstrap.macos.dock].apps: expected an absolute or ~/ application path: {value}","messagePattern":"\\[bootstrap\\.macos\\.dock\\]\\.apps: expected an absolute or ~/ application path: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/defaults/dock.rs","lineNumber":26,"sourceCode":"    let DefaultsValue::Array(values) = value else {\n        eyre::bail!(\"[bootstrap.macos.dock].apps: expected an array of application paths\");\n    };\n    let mut paths = Vec::new();\n    let mut seen = std::collections::HashSet::new();\n    for value in values {\n        let DefaultsValue::Str(value) = value else {\n            eyre::bail!(\"[bootstrap.macos.dock].apps: expected an array of application paths\");\n        };\n        let path = if let Some(rest) = value.strip_prefix(\"~/\") {\n            eyre::ensure!(\n                !Path::new(rest).has_root(),\n                \"[bootstrap.macos.dock].apps: expected a path relative to home: {value}\"\n            );\n            crate::env::HOME.join(rest)\n        } else {\n            PathBuf::from(value)\n        };\n        eyre::ensure!(\n            path.is_absolute()\n                && path\n                    .extension()\n                    .is_some_and(|ext| ext.eq_ignore_ascii_case(\"app\"))\n                && !path.components().any(|c| matches!(c, Component::ParentDir))\n                && !value.contains('\\0'),\n            \"[bootstrap.macos.dock].apps: expected an absolute or ~/ application path: {value}\"\n        );\n        let path: PathBuf = path.components().collect();\n        eyre::ensure!(\n            seen.insert(crate::file::canonicalize_or_self(&path)),\n            \"duplicate Dock application: {}\",\n            path.display()\n        );\n        paths.push(path);\n    }\n    Ok(paths)\n}","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/defaults/dock.rs#L8-L44","documentation":"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.","triggerScenarios":"dock.apps entries like \"Applications/Foo.app\" (relative), \"/Applications/Foo\" (missing .app), \"/opt/../Applications/Foo.app\" (parent dir), or paths containing a NUL character.","commonSituations":"Forgetting the .app extension; using paths relative to the config file; typos introducing \"..\"; untrusted input injected into the apps list (path traversal attempt).","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"],"exampleFix":"// before\napps = [\"Applications/MyApp\"]\n// after\napps = [\"/Applications/MyApp.app\"]","handlingStrategy":"validation","validationCode":"fn validate_app_path(value: &str) -> Result<(), String> {\n    let p = Path::new(value);\n    let ok = p.is_absolute()\n        && p.extension().map_or(false, |e| e.eq_ignore_ascii_case(\"app\"))\n        && !p.components().any(|c| matches!(c, std::path::Component::ParentDir))\n        && !value.contains('\\0');\n    if !ok { return Err(format!(\"invalid app path: {value}\")); }\n    Ok(())\n}","typeGuard":"fn is_valid_app_path(value: &str) -> bool {\n    let p = Path::new(value);\n    p.is_absolute()\n        && p.extension().map_or(false, |e| e.eq_ignore_ascii_case(\"app\"))\n        && !p.components().any(|c| matches!(c, std::path::Component::ParentDir))\n        && !value.contains('\\0')\n}","tryCatchPattern":null,"preventionTips":["Always list full absolute paths ending in .app","Never build app paths from untrusted input (traversal risk)","Normalize paths before writing them into config"],"tags":["macos","dock","paths","validation"],"backgroundTag":"path-traversal-blocked","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}