Tencent/matrix · error · IllegalStateException

token with pid=$pid not found

Error message

token with pid=$pid not found

What it means

SupervisorService tracks subordinate processes in pidToToken/nameToToken maps. removeToken(pid) throws IllegalStateException("token with pid=$pid not found") when no ProcessToken is registered for the given pid, i.e. the process died or was never registered as a subordinate.

Solutions

  1. Check existence before removing (e.g. track known pids or catch IllegalStateException) and treat missing tokens as no-ops.
  2. Centralize token removal in one callback (binder death OR explicit removal) to avoid double removal.
  3. Refresh the pid from the live binding before calling removeToken.
  4. Use the returned ProcessToken flow idempotently: ignore "not found" as an expected race outcome.

Example fix

// before
val token = removeToken(pid)
// after
val token = try {
    removeToken(pid)
} catch (e: IllegalStateException) {
    MatrixLog.w(TAG, "token already removed for pid=$pid")
    null
}
Defensive patterns

Strategy: fallback

Validate before calling

val existing = supervisor.knownPids[pid]
if (existing != null) removeToken(pid)

Try / catch

val token = try {
    removeToken(pid)
} catch (e: IllegalStateException) {
    null // already removed or never registered — treat as no-op
}

Prevention

When it happens

Trigger: Calling removeToken(pid) for a pid that never connected to the supervisor, was already removed by a prior call, or whose binding died and was cleaned up by another code path (e.g. onServiceDisconnected).

Common situations: Handling binder-death callbacks where two listeners both try to remove the token; stale pid from a cached process record; race between process death handling and manual cleanup.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/supervisor/SupervisorService.kt:326

                by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ConcurrentHashMap() }
        private val nameToToken: ConcurrentHashMap<String, ProcessToken>
                by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ConcurrentHashMap() }

        fun addToken(token: ProcessToken) {
            pidToToken[token.pid] = token
            nameToToken[token.name] = token
        }

        fun getToken(pid: Int) = pidToToken[pid]
        fun getToken(name: String) = nameToToken[name]

        fun removeToken(pid: Int): ProcessToken {
            val rm = pidToToken.remove(pid)
            rm?.let {
                nameToToken.remove(rm.name)
                return rm
            }
            throw IllegalStateException("token with pid=$pid not found")
        }

        fun isEmpty(): Boolean =
            pidToToken.isEmpty() || pidToToken.all { it.key == Process.myPid() }

        fun removeToken(name: String): ProcessToken {
            val rm = nameToToken.remove(name)
            rm?.let {
                pidToToken.remove(rm.pid)
                return rm
            }
            throw IllegalStateException("token with name=$name not found")
        }
    }

    private class RemoteProcessLifecycleProxy(val token: ProcessToken) : StatefulOwner() {

        init {

View on GitHub (pinned to 3b8293bd65)