tauri-apps/tauri · error

failed to read kotlin file as string

Error message

failed to read kotlin file as string

What it means

This is a build-time panic from the Tauri crate's build script. During an Android build, the script reads every .kt template file from the Android codegen directory and substitutes {{package}}/{{library}} placeholders. If fs::read_to_string fails on any of those files (file missing, not readable, invalid UTF-8), the build script panics with this message and aborts compilation of the crate.

Solutions

  1. Verify the tauri source checkout is intact (git status / re-clone) so all codegen .kt files exist
  2. Check permissions on the kotlin_files_path directory and its files; ensure the build user can read them
  3. Ensure no other process (antivirus, IDE sync) is locking or modifying the files during build
  4. Update or pin the Tauri version; if caused by a packaging bug, report it to tauri-apps/tauri

Example fix

// cargo config: force a clean rebuild after fixing file state
// before
rm -rf target && cargo tauri android build
// after
cargo tauri android build
Defensive patterns

Strategy: validation

Validate before calling

let p = std::path::Path::new("crates/tauri/mobile/android-codegen");
assert!(p.is_dir(), "codegen dir missing");
for f in std::fs::read_dir(p).unwrap() {
    let f = f.unwrap().path();
    assert!(f.is_file(), "not a file: {}", f.display());
    assert!(std::fs::read(&f).is_ok(), "unreadable: {}", f.display());
}

Prevention

When it happens

Trigger: Running `cargo build` for an Android target while a file inside the Android codegen directory pointed to by kotlin_files_path cannot be read: it was deleted between read_dir and read, is unreadable due to filesystem permissions, or contains invalid UTF-8.

Common situations: A partially-checked-out or corrupted tauri source tree, a broken symlink inside the mobile android-codegen directory, antivirus/indexing tools locking files during build on Windows, or filesystem permission issues after running the build as a different user (e.g. sudo).

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18). Data as JSON: /api/errors/0bf1de7f7717033e. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri/build.rs:306

      let kotlin_out_dir = PathBuf::from(&kotlin_out_dir)
        .canonicalize()
        .unwrap_or_else(move |_| {
          panic!(
            "Failed to canonicalize `WRY_ANDROID_KOTLIN_FILES_OUT_DIR` path {kotlin_out_dir:?}"
          )
        });

      let kotlin_files_path =
        PathBuf::from(env_var("CARGO_MANIFEST_DIR")).join("mobile/android-codegen");
      println!("cargo:rerun-if-changed={}", kotlin_files_path.display());
      let kotlin_files =
        fs::read_dir(kotlin_files_path).expect("failed to read Android codegen directory");

      for file in kotlin_files {
        let file = file.unwrap();

        let content = fs::read_to_string(file.path())
          .expect("failed to read kotlin file as string")
          .replace("{{package}}", &package)
          .replace("{{library}}", &library);

        let out_path = kotlin_out_dir.join(file.file_name());
        // Overwrite only if changed to not trigger rebuilds
        write_if_changed(&out_path, &content).expect("Failed to write kotlin file");

        println!("cargo:rerun-if-changed={}", out_path.display());
      }
    }

    if let Some(project_dir) = env::var_os("TAURI_ANDROID_PROJECT_PATH").map(PathBuf::from) {
      let package_unescaped = env::var("TAURI_ANDROID_PACKAGE_UNESCAPED")
        .unwrap_or_else(|_| env_var("WRY_ANDROID_PACKAGE").replace('`', ""));
      let tauri_proguard =
        include_str!("./mobile/proguard-tauri.pro").replace("$PACKAGE", &package_unescaped);
      std::fs::write(
        project_dir.join("app").join("proguard-tauri.pro"),

View on GitHub (pinned to 460ec35447)