tauri-apps/tauri · critical · tauri_cli::error::Error

Library from {} does not include required runtime symbols. T

Error message

Library from {} does not include required runtime symbols. This means you are likely missing the tauri::mobile_entry_point macro usage, see the documentation for more information: https://v2.tauri.app/start/migrate/from-tauri-1

What it means

`validate_lib` opens the produced static library and scans its symbols for one containing `start_app` — the marker emitted by the `#[cfg_attr(mobile, tauri::mobile_entry_point)]` macro. If no such symbol exists, the Rust library cannot boot the Tauri runtime on iOS, so the Xcode build is stopped with a migration hint.

Source

Thrown at crates/tauri-cli/src/mobile/ios/xcode_script.rs:345

    let mut obj_bytes = Vec::new();
    entry
      .read_to_end(&mut obj_bytes)
      .fs_context("failed to read mobile lib entry", path.to_path_buf())?;

    let file = object::File::parse(&*obj_bytes)
      .map_err(std::io::Error::other)
      .fs_context("failed to parse mobile lib entry", path.to_path_buf())?;
    for symbol in file.symbols() {
      let Ok(name) = symbol.name() else {
        continue;
      };
      if name.contains("start_app") {
        return Ok(());
      }
    }
  }

  crate::error::bail!(
    "Library from {} does not include required runtime symbols. This means you are likely missing the tauri::mobile_entry_point macro usage, see the documentation for more information: https://v2.tauri.app/start/migrate/from-tauri-1",
    path.display()
  )
}

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Annotate your main function: `#[cfg_attr(mobile, tauri::mobile_entry_point)]` above `pub fn run()` in `src-tauri/src/lib.rs`, and call `run()` from `main.rs`.
  2. Or run `tauri migrate` to apply the v1->v2 entry point changes automatically.
  3. Verify the symbol landed: `nm -gU target/aarch64-apple-ios/debug/lib<name>.a | grep start_app`.
  4. Clean and rebuild so the macro is actually expanded (`cargo clean` then rebuild in Xcode).

Example fix

// before (src-tauri/src/lib.rs)
pub fn run() {
  tauri::Builder::default().run(tauri::generate_context!()).unwrap();
}

// after
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
  tauri::Builder::default().run(tauri::generate_context!()).unwrap();
}
// src-tauri/src/main.rs keeps: fn main() { myapp_lib::run() }
Defensive patterns

Strategy: validation

Validate before calling

# Confirm the entry-point symbol before opening Xcode
nm -gU src-tauri/target/aarch64-apple-ios/debug/lib*.a | grep -q start_app \
  && echo "entry point ok" || echo "missing #[tauri::mobile_entry_point]"

Prevention

When it happens

Trigger: The app's `main` is not annotated with `tauri::mobile_entry_point` (only the desktop `fn main` exists), the attribute is missing the `#[cfg_attr(mobile, ...)]` guard so it was compiled out, or the project was migrated from Tauri 1.x by hand without running the migration.

Common situations: Tauri 1 -> 2 migration where the entry point refactor was skipped; a new iOS target added to an existing desktop app; refactoring that moved `main` out of lib.rs and dropped the macro.

Related errors


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