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

  1. Re-create the plugin instance (and its Matrix) after destroy instead of calling start on the old one.
  2. Check plugin.isPluginDestroyed() before calling start().
  3. 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

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


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)