Tencent/matrix · error · IllegalStateException

Closed during initialization

Error message

Closed during initialization

What it means

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.

Solutions

  1. Only call closeDatabase after a successful getDatabase() has returned at least once.
  2. Serialize lifecycle: perform init (getDatabase) on a single thread before allowing close paths.
  3. Avoid closing during Application startup/teardown races; guard close with the same lock used by getDatabase.
  4. Check for leaked async tasks that close the db while lint is initializing.

Example fix

// before
new Thread(() -> ownDatabase.closeDatabase()).start(); // races first getDatabase()
// after
synchronized (ownDatabase) { // after initial getDatabase() completed
    ownDatabase.closeDatabase();
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure a prior getDatabase() completed before closing
if (!databaseOpenedOnce) { skipClose(); }

Try / catch

try {
    ownDatabase.closeDatabase();
} catch (IllegalStateException e) {
    // initialization still in progress; retry after init completes
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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

Appendix: source

Thrown at matrix/matrix-android/matrix-sqlite-lint/matrix-sqlite-lint-android-sdk/src/full/java/com/tencent/sqlitelint/behaviour/persistence/SQLiteLintOwnDatabase.java:86

    private volatile SQLiteDatabase mDatabase;
    private boolean mIsInitializing;

    public SQLiteDatabase getDatabase() {
        if (mDatabase == null || !mDatabase.isOpen()) {
            synchronized (this) {
                if (mDatabase == null || !mDatabase.isOpen()) {
                    mDatabase = openOrCreateDatabase();
                }
            }
        }

        return mDatabase;
    }

    public synchronized void closeDatabase() {
        if (mIsInitializing) {
            throw new IllegalStateException("Closed during initialization");
        }

        if (mDatabase != null && mDatabase.isOpen()) {
            mDatabase.close();
            mDatabase = null;
        }
    }

    private void onCreate(SQLiteDatabase db) {
        SLog.i(TAG, "onCreate");

        db.execSQL(IssueStorage.DB_VERSION_1_CREATE_SQL);
        for (int i = 0; i < IssueStorage.DB_VERSION_1_CREATE_INDEX.length; i++) {
            db.execSQL(IssueStorage.DB_VERSION_1_CREATE_INDEX[i]);
        }
    }

    private void onUpgrade(SQLiteDatabase db, int oldVersion) {

View on GitHub (pinned to 3b8293bd65)