Open-Source Wikis

/

Tauri

/

How to contribute

/

Debugging

tauri-apps/tauri

Debugging

A practical guide to chasing problems in Tauri. The repo is large and three different toolchains can be involved (Rust, Node/TS, Kotlin/Swift), so this page is organised by the symptom you're looking at.

Logs and tracing

The core crate gates structured logs behind the tracing Cargo feature:

tauri = { version = "2", features = ["tracing"] }

When enabled, key paths are instrumented in:

  • crates/tauri/src/manager/
  • crates/tauri/src/ipc/
  • crates/tauri/src/protocol/
  • crates/tauri/src/plugin.rs

Use a tracing-subscriber (e.g. tracing-subscriber::fmt) in your downstream app to print spans for window startup, command dispatch, event emission, custom protocol requests, and the updater. Flagged spans are listed in the crate-level docs of crates/tauri/src/lib.rs.

For non-traced code paths the runtime uses the log crate. The CLI configures env_logger with structured output (crates/tauri-cli/src/lib.rs#try_run). Increase verbosity with --verbose (-v, -vv) or set TAURI_CLI_VERBOSITY=2.

Common symptoms

"Command X not allowed by ACL"

Symptom: invoke('foo') from JS fails with an authority error.

Where to look:

  1. RuntimeAuthority is constructed in crates/tauri/src/ipc/authority.rs. The error message tells you which capability is missing.
  2. The resolved ACL is generated at build time by crates/tauri-build/src/acl.rs from your app's src-tauri/capabilities/*.json and from the permissions/ directory of each plugin.
  3. Inspect the resolved ACL with cargo run -p tauri-cli -- inspect.
  4. Add or extend a capability JSON. See systems/acl-and-capabilities.

Webview "Failed to load: tauri://localhost"

Symptom: blank window, errors about the custom protocol.

Where to look:

  1. Custom protocols are registered in crates/tauri-runtime-wry/src/lib.rs (search for register_uri_scheme_protocol).
  2. The Tauri-side handler lives in crates/tauri/src/protocol/.
  3. If you see this only in production, check that your frontend bundle was actually embedded — tauri-codegen reads it from frontendDist in tauri.conf.json and embeds it via EmbeddedAssets (crates/tauri-codegen/src/embedded_assets.rs). A typo in frontendDist produces a runtime "asset not found".

Window flickers, decorations wrong, drag region misbehaves

Where to look: crates/tauri-runtime-wry/src/lib.rs (window plumbing) and crates/tauri-runtime-wry/src/undecorated_resizing.rs (the manual hit-testing for decorations: false windows). Drag-region handling sits in the JS API at packages/api/src/window.ts and is processed back in Rust.

Bundler produces a broken installer

Where to look:

  • DMG / .app: crates/tauri-bundler/src/bundle/macos/.
  • AppImage / Debian / RPM: crates/tauri-bundler/src/bundle/linux/.
  • MSI: crates/tauri-bundler/src/bundle/windows/msi/.
  • NSIS: crates/tauri-bundler/src/bundle/windows/nsis/.

The bundler uses handlebars for templated installer scripts; a mis-rendered template produces verbose logs at --verbose level.

Mobile: "JNI call failed" / "missing function"

The Android bridge generates Kotlin from crates/tauri/mobile/android/. Each plugin bound for mobile uses the macros in crates/tauri-macros and Rust-side dispatch in crates/tauri/src/plugin/mobile.rs. iOS uses Swift bindings under crates/tauri/mobile/ios/. Increase Tauri log verbosity and check the device log (adb logcat / Xcode console).

CLI hangs in dev mode

crates/tauri-cli/src/dev/: the dev command spawns the frontend dev server (e.g. Vite), waits for it to come up, then cargo runs the user app and reloads on Rust changes via cargo-watch-style file watching. A common hang is the dev server taking too long; the timeout is in helpers/. Run with -vv to see exact subprocess invocations.

Useful breakpoints when stepping with lldb/rust-lldb

Symbol Why
tauri::app::Builder::build Pre-flight: plugins, runtime, manager construction.
tauri::manager::AppManager::on_message First Rust frame for an incoming IPC message.
tauri::ipc::authority::RuntimeAuthority::resolve_access Where ACL accept/deny decisions happen.
tauri::plugin::PluginStore::on_event Plugin lifecycle hooks.
tauri_runtime_wry::Wry::run Top of the TAO event loop.

Reproducing CI locally

If you fail a CI check, the workflow files in .github/workflows/ show the exact commands. Most boil down to:

cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all -- --check
cargo test --workspace --all-features
pnpm format:check
pnpm eslint:check
pnpm ts:check
cargo run -p tauri-schema-generator       # for check-generated-files.yml

For container-based reproduction the repo ships .docker/ and .devcontainer/ which mirror CI's Linux image.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Debugging – Tauri wiki | Factory