Tencent/matrix · error · RuntimeException

plugin start, plugin listener is null

Error message

plugin start, plugin listener is null

What it means

Plugin.start() requires the PluginListener passed to init(); it flips status to PLUGIN_STARTED before checking the listener, so a null listener throws after the status change. The listener is how the SDK notifies your code of plugin start.

Solutions

  1. Always call plugin.init(application, pluginListener) with a non-null listener before start().
  2. Ensure the Matrix.Builder build path (which injects the listener) is used rather than manual construction.
  3. Pass a no-op PluginListener if no callbacks are needed.

Example fix

// before
Plugin p = new MyPlugin();
p.start();
// after
Plugin p = new MyPlugin();
p.init(application, new DefaultPluginListener());
p.start();
Defensive patterns

Strategy: validation

Validate before calling

if (app != null && listener != null) {
    plugin.init(app, listener);
    plugin.start();
}

Try / catch

try {
    plugin.start();
} catch (RuntimeException e) {
    Log.e(TAG, "plugin listener missing at start", e);
}

Prevention

When it happens

Trigger: Plugin.start() when init(app, null) was called or the plugin was constructed without going through init.

Common situations: Manual plugin instantiation in unit tests without init; passing a null listener intentionally; deserialized or rebuilt plugin objects losing the listener reference.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/e8397069f000b44d. Report an issue: GitHub.

Appendix: source

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

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

        status = PLUGIN_STOPPED;

        if (pluginListener == null) {
            throw new RuntimeException("plugin stop, plugin listener is null");

View on GitHub (pinned to 3b8293bd65)