{"record":{"id":"64f2197e44a8d0e9","repo":"tauri-apps/tauri","slug":"failed-to-extract-external-binary-filename-64f219","errorCode":null,"errorMessage":"failed to extract external binary filename","messagePattern":"failed to extract external binary filename","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-bundler/src/bundle/windows/msi/mod.rs","lineNumber":929,"sourceCode":"    }\n\n    output_paths.push(msi_path);\n  }\n\n  Ok(output_paths)\n}\n\n/// Generates the data required for the external binaries and extra binaries bundling.\nfn generate_binaries_data(settings: &Settings) -> crate::Result<Vec<Binary>> {\n  let mut binaries = Vec::new();\n  let cwd = std::env::current_dir()?;\n  let tmp_dir = std::env::temp_dir();\n  for src in settings.external_binaries() {\n    let src = src?;\n    let binary_path = cwd.join(&src);\n    let dest_filename = src\n      .file_name()\n      .expect(\"failed to extract external binary filename\")\n      .to_string_lossy()\n      .replace(&format!(\"-{}\", settings.target()), \"\");\n    let dest = tmp_dir.join(&dest_filename);\n    std::fs::copy(binary_path, &dest)?;\n\n    binaries.push(Binary {\n      guid: Uuid::new_v4().to_string(),\n      path: dest\n        .into_os_string()\n        .into_string()\n        .expect(\"failed to read external binary path\"),\n      id: wix_identifier(&dest_filename),\n    });\n  }\n\n  for bin in settings.binaries() {\n    if !bin.main() {\n      binaries.push(Binary {","sourceCodeStart":911,"sourceCodeEnd":947,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-bundler/src/bundle/windows/msi/mod.rs#L911-L947","documentation":"generate_binaries_data copies each external binary (sidecar, from bundle.externalBin) into the temp directory and derives its MSI file id from the source's file_name. file_name() is None when the path is a root or ends with '..', so a degenerate externalBin path panics during MSI data generation.","triggerScenarios":"MSI bundling (tauri build --bundles msi) with a bundle.externalBin entry such as '..' or a directory-like path lacking a final file component, so src.file_name() returns None.","commonSituations":"Same class as the Linux sidecar failure: script-generated configs with empty variable interpolation or typos; only surfaces on Windows MSI builds because this code path is MSI-specific.","solutions":["Fix the externalBin entry to name the sidecar file with its target-triple suffix, e.g. binaries/my-sidecar-x86_64-pc-windows-msvc.exe","Check generated tauri.conf.json for unset variables or copy-paste typos that strip the file name","Confirm the sidecar file exists with the -<target> suffix before bundling"],"exampleFix":"// tauri.conf.json — before\n\"externalBin\": [\"binaries/..\"]\n\n// after\n\"externalBin\": [\"binaries/my-sidecar-x86_64-pc-windows-msvc.exe\"]","handlingStrategy":"validation","validationCode":"// validate externalBin entries before MSI bundling\nconst last = (p) => p.split('/').pop() ?? '';\nconst bad = (config.bundle.externalBin ?? []).filter((p) => ['', '.', '..'].includes(last(p)));\nif (bad.length) throw new Error(`externalBin entries without a file name: ${bad.join(', ')}`);","typeGuard":"const hasSidecarFileName = (p) => { const seg = p.split('/').pop() ?? ''; return seg.length > 0 && seg !== '.' && seg !== '..'; };","tryCatchPattern":null,"preventionTips":["Every externalBin entry must name a file (with the -<target-triple> suffix), not a directory","Validate generated tauri.conf.json with its JSON schema in CI","Fail on empty variable interpolation when generating config files"],"tags":["windows","msi","sidecar","external-binary","path","tauri-bundler"],"backgroundTag":"invalid-path","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}