Tencent/matrix · error · NullPointerException

closer == null

Error message

closer == null

What it means

MatrixCloseGuard.open(closer) throws NullPointerException when the caller passes a null closer name. The name is used to build the 'Explicit termination method not called' leak-report message, so it must be a non-null method name like 'close()' or 'release()'. Unlike most checks here, this validation runs even when CloseGuard is disabled, so it fails fast regardless of configuration.

Solutions

  1. Pass a concrete non-null termination-method name to open(), e.g. open("close") or open("release")
  2. If the name is computed, default it before calling: open(name != null ? name : "close")
  3. Check the caller site for reflective lookups that can return null and handle the null before calling open

Example fix

// before
guard.open(closeMethodName); // closeMethodName may be null
// after
guard.open(closeMethodName != null ? closeMethodName : "close");
Defensive patterns

Strategy: validation

Validate before calling

if (closerName == null) throw new IllegalArgumentException("closer name required"); guard.open(closerName);

Type guard

boolean isValidCloser(String s) { return s != null && !s.isEmpty(); }

Try / catch

try { guard.open(name); } catch (NullPointerException e) { log.error("open(null): pass a termination method name", e); }

Prevention

When it happens

Trigger: Calling closeGuard.open(null) directly, or passing a variable that resolves to null (e.g. a method name looked up reflectively that returned null).

Common situations: Wrapping a resource class whose close-method name is derived from configuration or reflection; refactoring code that used to pass a constant string; unit tests that pass null placeholders.

Related errors


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

Appendix: source

Thrown at matrix/matrix-android/matrix-io-canary/src/main/java/com/tencent/matrix/iocanary/detect/MatrixCloseGuard.java:179

        return sREPORTER;
    }

    private MatrixCloseGuard() {
    }

    /**
     * If CloseGuard is enabled, {@code open} initializes the instance
     * with a warning that the caller should have explicitly called the
     * {@code closer} method instead of relying on finalization.
     *
     * @param closer non-null name of explicit termination method
     * @throws NullPointerException if closer is null, regardless of
     *                              whether or not CloseGuard is enabled
     */
    public void open(String closer) {
        // always perform the check for valid API usage...
        if (closer == null) {
            throw new NullPointerException("closer == null");
        }
        // ...but avoid allocating an allocationSite if disabled
        if (this == NOOP || !sENABLED) {
            return;
        }
        String message = "Explicit termination method '" + closer + "' not called";
        allocationSite = new Throwable(message);
    }

    private Throwable allocationSite;

    /**
     * Marks this CloseGuard instance as closed to avoid warnings on
     * finalization.
     */
    public void close() {
        allocationSite = null;
    }

View on GitHub (pinned to 3b8293bd65)