Tencent/matrix · error · IllegalStateException
Found resource cycle!
Error message
Found resource cycle! <visitPath>
What it means
During unused-resource reference resolution, readChildReference() does a DFS over the resource dependency graph and throws IllegalStateException when a resource references another resource already on the current visit path — i.e., a cycle. The message includes the cycle path stack for debugging.
Solutions
- Inspect the cycle path in the message and refactor one resource to break the cycle
- Exclude the cyclic resources from analysis via the ignore-resources param (PARAM_IGNORE_RESOURCES_LIST)
- Update Matrix — newer versions may treat cycles as terminal instead of throwing
Example fix
// gradle param // before params: unused-resources without ignore list // after params.put(JobConstants.PARAM_IGNORE_RESOURCES_LIST, "drawable/cycle_a,drawable/cycle_b");
Defensive patterns
Strategy: try-catch
Validate before calling
// inspect the reported cycle path in the message before re-running String msg = e.getMessage(); // "Found resource cycle! [a, b, a]" — add these to ignore list
Try / catch
try {
TaskResult r = task.call();
} catch (Exception e) {
if (e.getMessage() != null && e.getMessage().startsWith("Found resource cycle!")) {
// add cycle members to PARAM_IGNORE_RESOURCES_LIST and retry
} else {
throw e;
}
} Prevention
- Avoid mutually-referencing resources (drawables/alias cycles)
- Add known cyclic resources to the ignore-resources list
- Keep Matrix updated for cycle-handling fixes
When it happens
Trigger: AAPT/resource definitions where resources reference each other cyclically (e.g., drawable A references drawable B which references A), encountered while recursively decoding resources.
Common situations: Exotic resource setups: vector drawables, drawables with theme attributes, or generated resources with mutual references; also triggered by unusual custom resource merging.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Matrix init, Matrix should not be null.
- you must init Matrix sdk first
- matrix init, application is null
- plugin with tag is already exist
- plugin duplicate init, application or plugin listener is…
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/9bcfde7d76ddc849.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-apk-canary/src/main/java/com/tencent/matrix/apk/model/task/UnusedResourcesTask.java:464
for (String pattern : ignoreSet) {
if (name.matches(pattern)) {
return true;
}
}
return false;
}
private void readChildReference(String resource) throws IllegalStateException {
if (nonValueReferences.containsKey(resource)) {
visitPath.push(resource);
Set<String> childReference = nonValueReferences.get(resource);
unusedResSet.removeAll(childReference);
for (String reference : childReference) {
if (!visitPath.contains(reference)) {
readChildReference(reference);
} else {
visitPath.push(reference);
throw new IllegalStateException("Found resource cycle! " + visitPath.toString());
}
}
visitPath.pop();
}
}
@Override
public TaskResult call() throws TaskExecuteException {
try {
TaskResult taskResult = TaskResultFactory.factory(type, TaskResultFactory.TASK_RESULT_TYPE_JSON, config);
long startTime = System.currentTimeMillis();
readMappingTxtFile();
readResourceTxtFile();
ResguardUtil.readResMappingTxtFile(resMappingTxt, null, resguardMap);
unusedResSet.addAll(resourceDefMap.values());
Log.i(TAG, "find resource declarations %d items.", unusedResSet.size());
decodeCode();View on GitHub (pinned to 3b8293bd65)