shwenzhang/AndResGuard · error · brut.androlib.AndrolibException
now can only proguard less than 35594 in a single type
Error message
now can only proguard less than 35594 in a single type
What it means
ARSCDecoder's proguard string pool pre-generates a fixed buffer (mReplaceStringBuffer) of short replacement resource names (roughly 35,594 entries, 0x8b0a limit imposed by arsc string encoding constraints). When more resource entries in a single type need replacement names than the buffer holds, getReplaceString finds it empty and throws. It is a hard capacity limit of the obfuscator, not a corruption error.
Solutions
- Split resources into additional types/packages or use resource shrinking (remove unused resources) to get under the ~35594-per-type limit
- Enable R8/ProGuard resource shrinking and remove unused drawables before obfuscating
- Move bulk resources into a separate dynamic-feature/library module with its own package
- Upgrade AndResGuard in case newer releases raise or parameterize the limit
Example fix
// before: 40000 drawables in one type
// after: enable shrinking in build.gradle
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
} Defensive patterns
Strategy: validation
Validate before calling
// count entries per resource type before running obfuscation
long drawables = countEntriesOfType(apk, "drawable");
if (drawables >= 35594) {
throw new GradleException("Type 'drawable' has " + drawables + " entries; shrink below 35594 or split packages");
} Try / catch
try {
andResGuardTask.execute();
} catch (AndrolibException e) {
if (e.getMessage().contains("35594")) {
throw new GradleException("Too many resources in a single type — shrink resources or split modules", e);
}
throw e;
} Prevention
- Enable shrinkResources + minifyEnabled in release builds
- Remove unused/generated drawables before obfuscation
- Split very large apps into feature/dynamic modules
- Alert in CI when any resource type approaches ~35k entries
When it happens
Trigger: A single resource type in the APK contains >= ~35594 entries, exhausting the pre-built replacement-name pool when each entry requests a new obfuscated name via getReplaceString().
Common situations: Extremely large apps (often merged/super apps or apps with many generated resources) with tens of thousands of drawables/layouts/strings in one type.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Failed to obtain key with alias
- entry " " does not contain certificates
- Private key file (--key) must be specified
- Certificate file (--cert) must be specified
- Failed to parse encrypted private key blob
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/0faf53b99b0acbef.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/ARSCDecoder.java:1198
public boolean isReplaced(int id) {
return mIsReplaced.contains(id);
}
public boolean isInWhiteList(int id) {
return mIsWhiteList.contains(id);
}
public void setInWhiteList(int id) {
mIsWhiteList.add(id);
}
public void setInReplaceList(int id) {
mIsReplaced.add(id);
}
public String getReplaceString() throws AndrolibException {
if (mReplaceStringBuffer.isEmpty()) {
throw new AndrolibException(String.format("now can only proguard less than 35594 in a single type\n"));
}
return mReplaceStringBuffer.remove(0);
}
}
}View on GitHub (pinned to e4df245d82)