Tencent/matrix · error · RuntimeException

plugin start, but plugin has been already started

Error message

plugin start, but plugin has been already started

What it means

Thrown from Plugin.start() when the plugin is already in PLUGIN_STARTED state. start() is intended to be called exactly once per plugin lifecycle; a second call means the caller (usually Matrix.onCreate) is double-starting the plugin, so the guard throws rather than re-invoking onStart and re-registering the plugin with its listener.

Solutions

  1. Guard start with plugin.isPluginStarted() before calling.
  2. Track whether startAllPlugins() has run (e.g. a boolean in your Application).
  3. Call stop() before start() if a restart is intended.

Example fix

// before
if (!plugin.isPluginStarted()) {
    plugin.start();
}
plugin.start();
// after
if (!plugin.isPluginStarted()) {
    plugin.start();
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!plugin.isPluginStarted() && !plugin.isPluginDestroyed()) {
    plugin.start();
}

Type guard

boolean canStart(Plugin p) { return !p.isPluginStarted() && !p.isPluginDestroyed(); }

Try / catch

try {
    plugin.start();
} catch (RuntimeException e) {
    Log.w(TAG, "plugin already started", e);
}

Prevention

When it happens

Trigger: Calling plugin.start() (or Matrix.with().startAllPlugins()) twice without an intervening stop().

Common situations: Calling startAllPlugins() in both Application.onCreate and onForeground; re-entry from lifecycle callbacks; duplicated bootstrap code paths.

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/f4a396434f523c28. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/plugin/Plugin.java:102

        }

        //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");
        }

        if (!isPluginStarted()) {
            throw new RuntimeException("plugin stop, but plugin is never started");

View on GitHub (pinned to 3b8293bd65)