{"record":{"id":"b70d7c5eb057b97f","repo":"tauri-apps/tauri","slug":"failed-to-read-plugin-global-api-script-paths","errorCode":null,"errorMessage":"failed to read plugin global API script paths","messagePattern":"failed to read plugin global API script paths","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-utils/src/plugin.rs","lineNumber":70,"sourceCode":"      scripts.insert(0, tauri_global_scripts);\n    }\n\n    fs::write(\n      out_dir.join(GLOBAL_API_SCRIPT_FILE_LIST_PATH),\n      serde_json::to_string(&scripts).expect(\"failed to serialize global API script paths\"),\n    )\n    .expect(\"failed to write global API script\");\n  }\n\n  /// Read global api scripts from [`GLOBAL_API_SCRIPT_FILE_LIST_PATH`]\n  pub fn read_global_api_scripts(out_dir: &Path) -> Option<Vec<String>> {\n    let global_scripts_path = out_dir.join(GLOBAL_API_SCRIPT_FILE_LIST_PATH);\n    if !global_scripts_path.exists() {\n      return None;\n    }\n\n    let global_scripts_str = fs::read_to_string(global_scripts_path)\n      .expect(\"failed to read plugin global API script paths\");\n    let global_scripts = serde_json::from_str::<Vec<PathBuf>>(&global_scripts_str)\n      .expect(\"failed to parse plugin global API script paths\");\n\n    Some(\n      global_scripts\n        .into_iter()\n        .map(|p| {\n          fs::read_to_string(&p).unwrap_or_else(|e| {\n            panic!(\n              \"failed to read plugin global API script {}: {e}\",\n              p.display()\n            )\n          })\n        })\n        .collect(),\n    )\n  }\n}","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-utils/src/plugin.rs#L52-L88","documentation":"read_global_api_scripts reads back <out_dir>/__global-api-script.js written during the build. The exists() check already passed, so the expect fires only on an IO-level read failure: the file was deleted between check and read, permission was lost, or the content is not valid UTF-8 (e.g. truncated by an interrupted build).","triggerScenarios":"A stale or half-written __global-api-script.js left in OUT_DIR by an interrupted or killed build; concurrent builds sharing one OUT_DIR; corrupted artifacts.","commonSituations":"Killing cargo mid-build and rebuilding into the same target dir; CI caching target/ with corrupted files; encoding corruption of the artifact.","solutions":["Clean the artifacts: cargo clean (or delete the crate's OUT_DIR under target/) so the file is regenerated.","Avoid running concurrent builds against the same target directory.","If it persists, inspect the file: it must be a valid UTF-8 JSON array of paths."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let p = out_dir.join(tauri_utils::plugin::GLOBAL_API_SCRIPT_FILE_LIST_PATH);\nif let Ok(raw) = std::fs::read(&p) {\n    if std::str::from_utf8(&raw).is_err() {\n        std::fs::remove_file(&p).ok(); // force regeneration next build\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not share one target directory between concurrent builds.","Clean the workspace after interrupted builds.","Treat repeated failures here as corrupted artifacts and cargo clean."],"tags":["tauri","build-script","out-dir","corrupted-artifact"],"backgroundTag":"corrupted-build-artifact","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","contentChangedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}