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

  1. Split resources into additional types/packages or use resource shrinking (remove unused resources) to get under the ~35594-per-type limit
  2. Enable R8/ProGuard resource shrinking and remove unused drawables before obfuscating
  3. Move bulk resources into a separate dynamic-feature/library module with its own package
  4. 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

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


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)