Tencent/matrix · error · IllegalAccessException

NOT allow for subordinate processes

Error message

NOT allow for subordinate processes

What it means

ProcessSubordinate.manager is a lazy singleton exposing the subordinate management API. On a supervisor process the lazy initializer builds the Manager; on a subordinate process it throws IllegalAccessException("NOT allow for subordinate processes"), because managing subordinate proxies is exclusively a supervisor capability.

Solutions

  1. Only access ProcessSubordinate.manager inside code guarded by ProcessSupervisor.isSupervisor.
  2. Restructure shared logic so manager access lives in supervisor-only classes or modules.
  3. Verify ProcessSupervisor.init was called with a configuration that makes this process the supervisor (service declaration, enable flags).
  4. Catch IllegalAccessException around the manager access when process role is not statically known.

Example fix

// before
val manager = ProcessSubordinate.manager
// after
if (ProcessSupervisor.isSupervisor) {
    val manager = ProcessSubordinate.manager
}
Defensive patterns

Strategy: validation

Validate before calling

if (!ProcessSupervisor.isSupervisor) {
    MatrixLog.w(TAG, "manager is supervisor-only")
    return
}
val manager = ProcessSubordinate.manager

Type guard

fun subordinateManagerOrNull(): ProcessSubordinate.Manager? =
    if (ProcessSupervisor.isSupervisor) ProcessSubordinate.manager else null

Try / catch

val manager = try {
    ProcessSubordinate.manager
} catch (e: IllegalAccessException) {
    MatrixLog.w(TAG, "not a supervisor process", e)
    null
}

Prevention

When it happens

Trigger: Accessing ProcessSubordinate.manager from a process where ProcessSupervisor.isSupervisor is false — e.g. a subordinate process touching the manager to enumerate or manipulate subordinate proxies.

Common situations: Shared code paths that touch ProcessSubordinate on both process types; debugging session where the app ran as a subordinate; misconfigured supervisor service enabling so the expected supervisor became a subordinate.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

    fun addDyingListener(listener: (recentScene: String?, processName: String?, pid: Int?) -> Boolean)
    fun removeDyingListener(listener: (recentScene: String?, processName: String?, pid: Int?) -> Boolean)
    fun addDeathListener(listener: (recentScene: String?, processName: String?, pid: Int?, isLruKill: Boolean?) -> Unit)
    fun removeDeathListener(listener: (recentScene: String?, processName: String?, pid: Int?, isLruKill: Boolean?) -> Unit)
    fun getRecentScene(): String
}

/**
 * Created by Yves on 2021/12/30
 */
internal object ProcessSubordinate {

    private val TAG by lazy { "${ProcessSupervisor.tag}.Subordinate" }

    internal val manager by lazy {
        if (ProcessSupervisor.isSupervisor) {
            Manager()
        } else {
            throw IllegalAccessException("NOT allow for subordinate processes")
        }
    }

    internal class Manager {
        private val subordinateProxies by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ConcurrentHashMap<ProcessToken, ISubordinateProxy>() }

        private fun Map<ProcessToken, ISubordinateProxy>.forEachSafe(action: (Map.Entry<ProcessToken, ISubordinateProxy>) -> Unit) {
            forEach { e ->
                safeLet(unsafe = { action(e) }, failed = {
                    MatrixLog.printErrStackTrace(TAG, it, "${e.key.pid}${e.key.name}")
                    if (it is DeadObjectException) {
                        MatrixLog.e(TAG, "remote process of proxy is dead, remove proxy: ${e.key}")
                        subordinateProxies.remove(e.key)
                    }
                })
            }
        }

View on GitHub (pinned to 3b8293bd65)