tauri-apps/tauri · error · std::io::Error

source does not exist

Error message

source does not exist

What it means

tauri-cli's copy_file helper guards every copy by first checking from.exists(); when the source path is missing it returns Error::Fs with context 'failed to copy file', the offending path, and an inner NotFound io::Error ('source does not exist'). The check exists to fail fast with a precise path instead of letting a raw OS error surface later.

Source

Thrown at crates/tauri-cli/src/helpers/fs.rs:18

// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use crate::{
  error::{Context, ErrorExt},
  Error,
};
use std::path::{Path, PathBuf};

pub fn copy_file(from: impl AsRef<Path>, to: impl AsRef<Path>) -> crate::Result<()> {
  let from = from.as_ref();
  let to = to.as_ref();
  if !from.exists() {
    Err(Error::Fs {
      context: "failed to copy file",
      path: from.to_path_buf(),
      error: std::io::Error::new(std::io::ErrorKind::NotFound, "source does not exist"),
    })?;
  }
  if !from.is_file() {
    Err(Error::Fs {
      context: "failed to copy file",
      path: from.to_path_buf(),
      error: std::io::Error::other("not a file"),
    })?;
  }
  let dest_dir = to.parent().expect("No data in parent");
  std::fs::create_dir_all(dest_dir)
    .fs_context("failed to create directory", dest_dir.to_path_buf())?;
  std::fs::copy(from, to).fs_context("failed to copy file", from.to_path_buf())?;
  Ok(())
}

/// Find an entry in a directory matching a glob pattern.
/// Currently does not traverse subdirectories.

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Compare the exact `path` field in the error against the filesystem, checking character case on Linux
  2. Fix the case or spelling in tauri.conf.json / code so it matches the real file
  3. If the file is generated, make sure the generating step runs and succeeds before the copy
  4. Re-run `tauri icon` or the codegen command, or restore the deleted file, then rebuild

Example fix

// before (tauri.conf.json): "licenseFile": "./LICENCE"  // actual file: LICENSE
// after:
"licenseFile": "./LICENSE"
Defensive patterns

Strategy: validation

Validate before calling

// Rust callers: verify source before copying
fn safe_copy(from: &std::path::Path, to: &std::path::Path) -> std::io::Result<u64> {
    let meta = std::fs::metadata(from)
        .map_err(|e| std::io::Error::new(e.kind(), format!("missing source {from:?}: {e}")))?;
    if !meta.is_file() {
        return Err(std::io::Error::other(format!("{from:?} is not a regular file")));
    }
    if let Some(dir) = to.parent() { std::fs::create_dir_all(dir)?; }
    std::fs::copy(from, to)
}

Prevention

When it happens

Trigger: Any tauri-cli/bundler code path that copies a declared file — icons, license files, templates, generated artifacts — where the source was deleted, misnamed, or never created by the step that was supposed to generate it. Note the exists() check is also a TOCTOU race: a file removed between check and copy still yields a raw OS error.

Common situations: Case-sensitivity mismatches that work on macOS/Windows but fail on Linux CI (Icon.png vs icon.png); paths pointing at files removed by cargo clean or excluded via gitignore; a codegen step skipped because an earlier command failed; stale config after a file rename.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20). Data as JSON: /api/errors/90b0a5d4ea91d772. Report an issue: GitHub.