Tencent/matrix · error · RuntimeException
plugin start, but plugin has been already destroyed
Error message
plugin start, but plugin has been already destroyed
What it means
Thrown from Plugin.start() when the plugin's internal status is PLUGIN_DESTROYED. Once a plugin has been destroyed its resources and listener wiring are torn down, so restarting it is not supported; any lifecycle orchestration that calls start() after destroy() indicates a programming error in the host app or Matrix itself and is rejected with this RuntimeException.
Solutions
- Re-create the plugin instance (and its Matrix) after destroy instead of calling start on the old one.
- Check plugin.isPluginDestroyed() before calling start().
- Do not destroy plugins you intend to stop/start again — use stop() instead.
Example fix
// before plugin.destroy(); plugin.start(); // after plugin.destroy(); Plugin plugin = new MyPlugin(); plugin.init(app, listener); plugin.start();
Defensive patterns
Strategy: type-guard
Validate before calling
if (!plugin.isPluginDestroyed()) {
plugin.start();
} Type guard
boolean canStart(Plugin p) { return !p.isPluginDestroyed() && !p.isPluginStarted(); } Try / catch
try {
plugin.start();
} catch (RuntimeException e) {
Log.e(TAG, "cannot start destroyed plugin", e);
} Prevention
- Never reuse plugin references after destroy()
- Use stop() for temporary suspension, destroy() only for final teardown
- Rebuild the whole Matrix (and plugins) after destroy
When it happens
Trigger: Calling plugin.start() after plugin.destroy() / Matrix.with().destroy() (or onDestroy lifecycle callback).
Common situations: Restart logic that calls start after teardown; keeping stale plugin references after Matrix destroy and reusing them; foreground/background listeners restarting destroyed plugins.
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
- plugin start, but plugin has been already started
- plugin start, plugin listener is null
- plugin stop, but plugin has been already destroyed
- plugin stop, but plugin is never started
- plugin with tag is already exist
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/8d5d2eddc0937bca.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/plugin/Plugin.java:98
content.put(Issue.ISSUE_REPORT_TIME, System.currentTimeMillis());
} catch (JSONException e) {
MatrixLog.e(TAG, "json error", e);
}
//MatrixLog.e(TAG, "detect issue:%s", issue);
pluginListener.onReportIssue(issue);
}
@Override
public Application getApplication() {
return application;
}
@Override
public void start() {
if (isPluginDestroyed()) {
throw new RuntimeException("plugin start, but plugin has been already destroyed");
}
if (isPluginStarted()) {
throw new RuntimeException("plugin start, but plugin has been already started");
}
status = PLUGIN_STARTED;
if (pluginListener == null) {
throw new RuntimeException("plugin start, plugin listener is null");
}
pluginListener.onStart(this);
}
@Override
public void stop() {
if (isPluginDestroyed()) {
throw new RuntimeException("plugin stop, but plugin has been already destroyed");View on GitHub (pinned to 3b8293bd65)