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
- Only invoke plugins that launch activities/permissions from the foreground UI context of the Tauri activity.
- Ensure your main activity extends the Tauri activity (`TauriActivity`) so the PluginManager registers it as the launch activity.
- Defer permission/launcher calls until the webview/activity is ready (e.g. after `onResume` / tauri 'ready' event).
- 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
- Invoke permission/launcher plugin APIs only while the app is foregrounded
- Extend TauriActivity so the PluginManager registers your activity
- Defer such calls until after the app 'ready' event
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
- No command found for plugin
- Android folder already exists
- Not all items are instances of the given type
- unexpected channel value $channelDef
- Android NDK invalid. Make sure the NDK_HOME environment…
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)