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
- Only access ProcessSubordinate.manager inside code guarded by ProcessSupervisor.isSupervisor.
- Restructure shared logic so manager access lives in supervisor-only classes or modules.
- Verify ProcessSupervisor.init was called with a configuration that makes this process the supervisor (service declaration, enable flags).
- 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
- Access ProcessSubordinate.manager only from supervisor-only components.
- Verify the supervisor service configuration so the intended process actually is the supervisor.
- Use runCatching around role-dependent singletons when the process role is dynamic.
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
- call forbidden
- Supervisor NOT initialized yet or Supervisor is disabled!!!
- backgroundLruKill should only be called in supervisor
- token with pid=$pid not found
- token with name=$name not found
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)