Tencent/matrix · error · IllegalArgumentException

obj is not closeable

Error message

obj ${obj} is not closeable

What it means

IOUtil.closeQuietly closes Closeable, ZipFile, and similar known closeable types while swallowing exceptions; if the object is none of the recognized types it throws IllegalArgumentException 'obj X is not closeable'. It's a programming-error guard: you passed something the utility doesn't know how to close.

Solutions

  1. Make the resource implement java.io.Closeable (or AutoCloseable and handle it) before passing to closeQuietly.
  2. Close it directly with try-with-resources instead of IOUtil.
  3. Add an instanceof branch in a local helper for the specific type (e.g. Channel) that IOUtil doesn't cover.
  4. Check for null first — a wrong variable being passed is the usual root cause.

Example fix

// before
IOUtil.closeQuietly(someChannel); // IllegalArgumentException
// after
if (someChannel instanceof Closeable) {
    IOUtil.closeQuietly(someChannel);
} else if (someChannel != null) {
    try { someChannel.close(); } catch (Throwable ignored) { }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (obj instanceof Closeable || obj instanceof ZipFile) {
    IOUtil.closeQuietly(obj);
}

Type guard

static boolean isCloseable(Object obj) {
    return obj instanceof Closeable || obj instanceof ZipFile;
}

Try / catch

try {
    IOUtil.closeQuietly(resource);
} catch (IllegalArgumentException e) {
    Log.w(TAG, "resource not closeable by IOUtil: " + resource.getClass());
}

Prevention

When it happens

Trigger: Passing an object that is neither Closeable nor ZipFile (e.g. a raw Channel type on an old API level, a custom resource, or null wrapper types) to IOUtil.closeQuietly.

Common situations: Refactoring a stream to a new resource class that doesn't implement Closeable; calling closeQuietly with AutoCloseable implementations that predate Closeable; misuse in tests with mocks that don't implement the interface.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at matrix/matrix-android/matrix-commons/src/main/java/com/tencent/matrix/javalib/util/IOUtil.java:143

            try {
                ((Closeable) obj).close();
            } catch (Throwable ignored) {
                // ignore
            }
        } else if (obj instanceof AutoCloseable) {
            try {
                ((AutoCloseable) obj).close();
            } catch (Throwable ignored) {
                // ignore
            }
        } else if (obj instanceof ZipFile) {
            try {
                ((ZipFile) obj).close();
            } catch (Throwable ignored) {
                // ignore
            }
        } else {
            throw new IllegalArgumentException("obj " + obj + " is not closeable");
        }
    }

    private IOUtil() {
        throw new UnsupportedOperationException();
    }
}

View on GitHub (pinned to 3b8293bd65)