{"record":{"id":"6235731ef1702784","repo":"Tencent/matrix","slug":"plugin-duplicate-init-application-or-plugin-liste","errorCode":null,"errorMessage":"plugin duplicate init, application or plugin listener is not null","messagePattern":"plugin duplicate init, application or plugin listener is not null","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/plugin/Plugin.java","lineNumber":54,"sourceCode":"    private static final String TAG = \"Matrix.Plugin\";\n\n    public static final int PLUGIN_CREATE = 0x00;\n    public static final int PLUGIN_INITED = 0x01;\n    public static final int PLUGIN_STARTED = 0x02;\n    public static final int PLUGIN_STOPPED = 0x04;\n    public static final int PLUGIN_DESTROYED = 0x08;\n\n    private PluginListener pluginListener;\n    private Application application;\n\n    private boolean isSupported = true;\n\n    private int status = PLUGIN_CREATE;\n\n    @Override\n    public void init(Application app, PluginListener listener) {\n        if (application != null || pluginListener != null) {\n            throw new RuntimeException(\"plugin duplicate init, application or plugin listener is not null\");\n        }\n        status = PLUGIN_INITED;\n        this.application = app;\n        this.pluginListener = listener;\n        listener.onInit(this);\n        ProcessUILifecycleOwner.INSTANCE.addListener(this);\n    }\n\n    @Override\n    public void onDetectIssue(Issue issue) {\n        if (issue.getTag() == null) {\n            // set default tag\n            issue.setTag(getTag());\n        }\n        issue.setPlugin(this);\n        JSONObject content = issue.getContent();\n        // add tag and type for default\n        try {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/plugin/Plugin.java#L36-L72","documentation":"Plugin.init(Application, PluginListener) stores the app and listener exactly once; calling it again while either field is still set means the plugin is being re-initialized and throws to protect state consistency.","triggerScenarios":"Calling plugin.init(app, listener) twice; Matrix.init being invoked twice with a Builder containing the same plugin instances.","commonSituations":"Re-calling Matrix.init on config change or hot-restart; adding the same plugin objects to two Matrix instances; re-running Application.onCreate logic in tests.","solutions":["Call init only once per plugin instance; create fresh Plugin instances if re-initialization is needed.","Avoid calling Matrix.init more than once per process.","In tests, construct new plugin objects per test instead of reusing them."],"exampleFix":"// before\nmatrixPlugin.init(app, listener);\nmatrixPlugin.init(app, listener2);\n// after\nmatrixPlugin.init(app, listener);\n// create a new instance if re-init is required\nPlugin fresh = new MyPlugin();\nfresh.init(app, listener2);","handlingStrategy":"validation","validationCode":"if (plugin.getApplication() == null && plugin.getPluginListener() == null) {\n    plugin.init(app, listener);\n}","typeGuard":null,"tryCatchPattern":"try {\n    plugin.init(app, listener);\n} catch (RuntimeException e) {\n    Log.e(TAG, \"plugin double init\", e);\n}","preventionTips":["Call init exactly once per plugin instance","Never call Matrix.init twice in one process","Create fresh plugins for each Matrix build in tests"],"tags":["android","plugins","initialization","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}