{"record":{"id":"1348df898d5f6b11","repo":"tauri-apps/tauri","slug":"failed-to-write-global-api-script","errorCode":null,"errorMessage":"failed to write global API script","messagePattern":"failed to write global API script","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-utils/src/plugin.rs","lineNumber":59,"sourceCode":"      let key = key.to_string_lossy();\n\n      if key == format!(\"DEP_TAURI_{GLOBAL_API_SCRIPT_PATH_KEY}\") {\n        tauri_global_scripts = Some(PathBuf::from(value));\n      } else if key.starts_with(\"DEP_\") && key.ends_with(GLOBAL_API_SCRIPT_PATH_KEY) {\n        let script_path = PathBuf::from(value);\n        scripts.push(script_path);\n      }\n    }\n\n    if let Some(tauri_global_scripts) = tauri_global_scripts {\n      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| {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-utils/src/plugin.rs#L41-L77","documentation":"save_global_api_scripts_paths writes a JSON array of the collected global API script paths to <out_dir>/__global-api-script.js. The expect fires when fs::write fails: out_dir does not exist, is read-only, the disk is full, or permissions deny writing.","triggerScenarios":"Calling save_global_api_scripts_paths with an out_dir that was never created (not the cargo-provided OUT_DIR), or writing on a read-only or full filesystem.","commonSituations":"Passing a custom directory instead of env OUT_DIR; CI sandboxes with restricted write access; disk exhaustion.","solutions":["Pass the cargo-provided OUT_DIR: std::env::var(\"OUT_DIR\").unwrap().","Create the directory first: std::fs::create_dir_all(out_dir)?.","Free disk space or fix directory permissions in the build environment."],"exampleFix":"// before\nsave_global_api_scripts_paths(Path::new(\"out\"), None); // 'out' may not exist\n\n// after\nlet out_dir = PathBuf::from(std::env::var(\"OUT_DIR\").unwrap());\nstd::fs::create_dir_all(&out_dir).unwrap();\nsave_global_api_scripts_paths(&out_dir, None);","handlingStrategy":"validation","validationCode":"let out_dir = std::path::PathBuf::from(std::env::var(\"OUT_DIR\").expect(\"OUT_DIR set by cargo\"));\nstd::fs::create_dir_all(&out_dir)?;\ntauri_utils::plugin::save_global_api_scripts_paths(&out_dir, None);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass cargo's OUT_DIR rather than a custom folder.","create_dir_all on the out dir before writing.","Keep build environments writable and monitored for disk space."],"tags":["tauri","build-script","plugin","io","out-dir"],"backgroundTag":"build-script-write-failed","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","contentChangedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}