Tencent/matrix · error · RuntimeException

plugin with tag is already exist

Error message

plugin with tag %s is already exist

What it means

Thrown from Matrix.Builder.plugin() when a plugin whose getTag() matches one already registered in the Builder's internal plugin set is added. Matrix keys plugins by tag, so duplicate registration would overwrite or shadow an existing plugin configuration; this guard rejects the duplicate at build time. Typically fires when the same plugin instance or two plugins sharing a tag are added before Matrix.create is called.

Solutions

  1. Remove the duplicate .plugin(...) call from the Builder chain.
  2. Use distinct tags for custom plugins by overriding getTag().
  3. Check existing plugins before adding: skip if the tag is already present.

Example fix

// before
builder.plugin(tracePlugin).plugin(tracePlugin);
// after
builder.plugin(tracePlugin);
Defensive patterns

Strategy: validation

Validate before calling

Set<String> seen = new HashSet<>();
for (Plugin p : myPlugins) {
    if (!seen.add(p.getTag())) {
        throw new IllegalStateException("duplicate plugin tag: " + p.getTag());
    }
}

Try / catch

try {
    builder.plugin(plugin);
} catch (RuntimeException e) {
    Log.e(TAG, "duplicate plugin tag", e);
}

Prevention

When it happens

Trigger: Calling builder.plugin(x) twice with the same plugin instance, or two different plugin instances whose getTag() return the same string (e.g. two TracePlugin configurations).

Common situations: Copy-pasted builder setup lines; a library dependency that also registers a Matrix plugin with a colliding tag; merge conflicts leaving duplicate .plugin(...) calls.

Related errors


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

Appendix: source

Thrown at matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/Matrix.java:151

//        private SupervisorConfig supervisorConfig;
//        private boolean          enableFgServiceMonitor;
//        private boolean          enableOverlayWindowMonitor;

        private final HashSet<Plugin> plugins = new HashSet<>();

        public Builder(Application app) {
            if (app == null) {
                throw new RuntimeException("matrix init, application is null");
            }
            this.application = app;
        }

        public Builder plugin(Plugin plugin) {
            String tag = plugin.getTag();
            for (Plugin exist : plugins) {
                if (tag.equals(exist.getTag())) {
                    throw new RuntimeException(String.format("plugin with tag %s is already exist", tag));
                }
            }
            plugins.add(plugin);
            return this;
        }

        public Builder pluginListener(PluginListener pluginListener) {
            this.pluginListener = pluginListener;
            return this;
        }

        public Builder matrixLifecycleConfig(MatrixLifecycleConfig config) {
            this.mLifecycleConfig = config;
            return this;
        }

        public Matrix build() {
            if (pluginListener == null) {

View on GitHub (pinned to 3b8293bd65)