{"record":{"id":"fd017a6bca49ef20","repo":"Tencent/matrix","slug":"closed-during-initialization","errorCode":null,"errorMessage":"Closed during initialization","messagePattern":"Closed during initialization","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-sqlite-lint/matrix-sqlite-lint-android-sdk/src/full/java/com/tencent/sqlitelint/behaviour/persistence/SQLiteLintOwnDatabase.java","lineNumber":86,"sourceCode":"\n    private volatile SQLiteDatabase mDatabase;\n    private boolean mIsInitializing;\n\n    public SQLiteDatabase getDatabase() {\n        if (mDatabase == null || !mDatabase.isOpen()) {\n            synchronized (this) {\n                if (mDatabase == null || !mDatabase.isOpen()) {\n                    mDatabase = openOrCreateDatabase();\n                }\n            }\n        }\n\n        return mDatabase;\n    }\n\n    public synchronized void closeDatabase() {\n        if (mIsInitializing) {\n            throw new IllegalStateException(\"Closed during initialization\");\n        }\n\n        if (mDatabase != null && mDatabase.isOpen()) {\n            mDatabase.close();\n            mDatabase = null;\n        }\n    }\n\n    private void onCreate(SQLiteDatabase db) {\n        SLog.i(TAG, \"onCreate\");\n\n        db.execSQL(IssueStorage.DB_VERSION_1_CREATE_SQL);\n        for (int i = 0; i < IssueStorage.DB_VERSION_1_CREATE_INDEX.length; i++) {\n            db.execSQL(IssueStorage.DB_VERSION_1_CREATE_INDEX[i]);\n        }\n    }\n\n    private void onUpgrade(SQLiteDatabase db, int oldVersion) {","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-sqlite-lint/matrix-sqlite-lint-android-sdk/src/full/java/com/tencent/sqlitelint/behaviour/persistence/SQLiteLintOwnDatabase.java#L68-L104","documentation":"SQLiteLintOwnDatabase.closeDatabase closes the underlying SQLiteDatabase, but if called while the database is mid-initialization (mIsInitializing == true, set inside getDatabase's synchronized openOrCreateDatabase flow), it throws IllegalStateException('Closed during initialization'). This prevents closing a database object that getDatabase is still constructing and returning.","triggerScenarios":"Calling closeDatabase from another thread (or re-entrantly) while getDatabase is still inside openOrCreateDatabase creating/upgrading the db — a race between a closer and the first opener.","commonSituations":"Shutdown/cleanup code racing first query on a cold start; a component calling closeDatabase before any getDatabase completed; concurrent use of the database object from multiple threads without going through getDatabase's synchronized block.","solutions":["Only call closeDatabase after a successful getDatabase() has returned at least once.","Serialize lifecycle: perform init (getDatabase) on a single thread before allowing close paths.","Avoid closing during Application startup/teardown races; guard close with the same lock used by getDatabase.","Check for leaked async tasks that close the db while lint is initializing."],"exampleFix":"// before\nnew Thread(() -> ownDatabase.closeDatabase()).start(); // races first getDatabase()\n// after\nsynchronized (ownDatabase) { // after initial getDatabase() completed\n    ownDatabase.closeDatabase();\n}","handlingStrategy":"validation","validationCode":"// ensure a prior getDatabase() completed before closing\nif (!databaseOpenedOnce) { skipClose(); }","typeGuard":null,"tryCatchPattern":"try {\n    ownDatabase.closeDatabase();\n} catch (IllegalStateException e) {\n    // initialization still in progress; retry after init completes\n}","preventionTips":["Serialize lifecycle: complete init on one thread before any close","Guard close paths with the same synchronization as getDatabase","Avoid background cleanup tasks racing first-use during cold start"],"tags":["sqlite","concurrency","lifecycle","illegal-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"}