{"record":{"id":"2e34cbfc3afc3e27","repo":"denoland/deno","slug":"invalid-output-dylib-path-has-no-file-name","errorCode":null,"errorMessage":"invalid --output: dylib path has no file name: {}","messagePattern":"invalid --output: dylib path has no file name: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/desktop.rs","lineNumber":3011,"sourceCode":"\n/// The pieces of `dylib_path` we feed into the bundlers, with proper\n/// error messages instead of `unwrap` panics on degenerate inputs like\n/// `--output /` or `--output .`.\nstruct DylibParts<'a> {\n  parent: &'a Path,\n  file_name: &'a std::ffi::OsStr,\n  app_name: String,\n}\n\nfn dylib_parts(dylib_path: &Path) -> Result<DylibParts<'_>, AnyError> {\n  let parent = dylib_path.parent().ok_or_else(|| {\n    deno_core::anyhow::anyhow!(\n      \"invalid --output: dylib path has no parent dir: {}\",\n      dylib_path.display()\n    )\n  })?;\n  let file_name = dylib_path.file_name().ok_or_else(|| {\n    deno_core::anyhow::anyhow!(\n      \"invalid --output: dylib path has no file name: {}\",\n      dylib_path.display()\n    )\n  })?;\n  let app_name = dylib_path\n    .file_stem()\n    .ok_or_else(|| {\n      deno_core::anyhow::anyhow!(\n        \"invalid --output: dylib path has no file stem: {}\",\n        dylib_path.display()\n      )\n    })?\n    .to_string_lossy()\n    .into_owned();\n  Ok(DylibParts {\n    parent,\n    file_name,\n    app_name,","sourceCodeStart":2993,"sourceCodeEnd":3029,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L2993-L3029","documentation":"Same DylibParts decomposition: Path::file_name() is None when the path ends in '..' or is exactly '.' — i.e. the --output value denotes a directory-ish path with no final file component, so there is no dylib file name to derive the app name from.","triggerScenarios":"Passing --output ., --output .., or a path whose last component normalizes away (trailing '..'), so dylib_path.file_name() returns None.","commonSituations":"A user points --output at a directory instead of a file (mental model 'output folder'); a script appends a slash or '..' due to variable expansion; CI config reused from a flag that expects a directory.","solutions":["Pass the full dylib file path, not a directory: --output ./build/libapp.dylib.","If you want the bundle in a given folder, name the file and let the bundler create the app alongside it.","Check shell scripts for stray trailing '/' or empty variable segments glued onto '..'."],"exampleFix":"# before\ndeno desktop compile --output ./build   # directory, no file name\n# error: invalid --output: dylib path has no file name: ./build\n\n# after\ndeno desktop compile --output ./build/libapp.dylib","handlingStrategy":"validation","validationCode":"// Guard: --output must be a file path (has a final component), not '.'/'..'/a dir\nfn is_file_path(p: &std::path::Path) -> bool {\n    p.file_name().map(|f| f != \".\" && f != \"..\").unwrap_or(false)\n}\nassert!(is_file_path(std::path::Path::new(&out)));\n// shell equivalent: case \"$out\" in .|..|*/) echo \"--output must be a file path\"; exit 1;; esac","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember --output takes the dylib FILE path (build/libapp.dylib), not an output folder.","Reject trailing slashes and bare '.'/'..' in wrapper scripts before invoking deno.","Derive the bundle location from the named file; the bundlers already place the .app next to it."],"tags":["cli","path","argument-validation","desktop"],"backgroundTag":"invalid-cli-path-argument","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}