tauri-apps/tauri · error · IllegalStateException

the plugin manager has no activity to launch from

Error message

the plugin manager has no activity to launch from

What it means

The Android `PluginManager` keeps launch activity launchers keyed by the current Activity. `currentLaunchers` throws `IllegalStateException` when looked up while `activity` is null or not a registered key — i.e. a plugin tries to start an activity-for-result (permission request, file picker, etc.) with no foreground activity.

Solutions

  1. Only invoke plugins that launch activities/permissions from the foreground UI context of the Tauri activity.
  2. Ensure your main activity extends the Tauri activity (`TauriActivity`) so the PluginManager registers it as the launch activity.
  3. Defer permission/launcher calls until the webview/activity is ready (e.g. after `onResume` / tauri 'ready' event).
  4. Update the tauri Android library so lifecycle re-registration on activity recreation is handled.

Example fix

// before
// background service
invokePlugin('Geolocation.requestPermissions') // no activity
// after
// inside webview/frontend after app ready
await listen('tauri://focus', () => invokePlugin('Geolocation.requestPermissions'));
Defensive patterns

Strategy: validation

Validate before calling

// Guard before invoking activity-dependent plugin APIs
if (document.visibilityState !== 'visible') {
  throw new Error('plugin launchers require a foreground activity');
}

Try / catch

// Kotlin side
try {
  requestPermissions(requiredPermissions) { ... }
} catch (e: IllegalStateException) {
  Log.e(TAG, "no activity to launch from", e)
}

Prevention

When it happens

Trigger: A plugin command requests permissions or launches an intent (camera, file chooser) while the app has no active Activity registered with the PluginManager — e.g. invoked from a background service, before `onCreate`/after `onDestroy`, or a custom Activity not extending Tauri's.

Common situations: Calling plugin APIs from background push handlers or workers; Activity recreated by configuration change without re-registering; custom launch Activity not using `TauriActivity`/the Tauri plugin lifecycle.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at crates/tauri/mobile/android/src/main/java/app/tauri/plugin/PluginManager.kt:95

      activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()
      ) { result ->
        startActivityForResultCallback?.onResult(result)
      },

      activity.registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()
      ) { result ->
        startIntentSenderForResultCallback?.onResult(result)
      },

      activity.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()
      ) { result ->
        requestPermissionsCallback?.onResult(result)
      }
    )

  private val currentLaunchers: ResultLaunchers
    get() = launchers[activity]
      ?: throw IllegalStateException("the plugin manager has no activity to launch from")

  fun onNewIntent(intent: Intent) {
    for (plugin in plugins.values) {
      plugin.instance.onNewIntent(intent)
    }
  }

  fun onPause(activity: AppCompatActivity) {
    for (plugin in plugins.values) {
      plugin.instance.triggerOnPause(activity)
    }
  }

  fun onResume(activity: AppCompatActivity) {
    for (plugin in plugins.values) {
      plugin.instance.triggerOnResume(activity)
    }
  }

View on GitHub (pinned to 460ec35447)