shwenzhang/AndResGuard · error
Invalid config file: Missing required attribute
Error message
Invalid config file: Missing required attribute
What it means
AndResGuard's Configuration parser throws this IOException when a <item> element inside the <whitelist> section of the config XML resolves to an empty (length 0) string, i.e. the required 'value' attribute is missing or blank. The whitelist is used to keep certain resource names untouched during obfuscation, so an empty entry is meaningless and treated as a malformed config. The library fails fast at parse time rather than silently producing a broken whitelist.
Solutions
- Add a non-empty value attribute to every <item> under <whitelist>, e.g. <item value="com.example.app.R.drawable.icon"/>
- Remove the empty <item> element entirely if no whitelist entries are needed
- Regenerate the config from the official sample config_file_and_resguard.xml and re-fill your values
Example fix
// before (config.xml) <issue id="whitelist"> <item value=""/> </issue> // after (config.xml) <issue id="whitelist"> <item value="com.example.app.R.drawable.ic_launcher"/> </issue>
Defensive patterns
Strategy: validation
Validate before calling
// before running AndResGuard with config.xml
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(configFile);
NodeList items = doc.getElementsByTagName("item");
for (int i = 0; i < items.getLength(); i++) {
Element e = (Element) items.item(i);
if (e.getParentNode().getNodeName().contains("whitelist") && e.getAttribute("value").isEmpty()) {
throw new IllegalStateException("whitelist item at index " + i + " has empty value");
}
} Try / catch
try {
new Configuration(configFile, ...);
} catch (IOException e) {
if (e.getMessage().contains("Missing required attribute")) {
// point the user to the offending <item> in the whitelist section
}
throw e;
} Prevention
- Never emit <item value=""/> from config generators — skip empty entries instead
- Lint your config XML for empty value attributes before the build
- Keep the whitelist in source control and review edits to it
When it happens
Trigger: Running AndResGuard with an XML config containing <whitelist><item value=""/></whitelist> or <item/> inside the whitelist issue; readWhiteListFromXml reads each item's value attribute and calls addWhiteList, which throws immediately when item.length()==0.
Common situations: Hand-edited config files where the value attribute was accidentally deleted or left empty; template configs with placeholder whitelist items never filled in; XML generation scripts emitting empty items for empty whitelist entries.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- please write the full package name,eg…
- Invalid config file: Missing required attribute
- Failed to obtain key with alias
- entry " " does not contain certificates
- Private key file (--key) must be specified
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/aae7f01e3e77bf16.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/com/tencent/mm/resourceproguard/Configuration.java:264
}
private void readWhiteListFromXml(Node node) throws IOException {
NodeList childNodes = node.getChildNodes();
if (childNodes.getLength() > 0) {
for (int j = 0, n = childNodes.getLength(); j < n; j++) {
Node child = childNodes.item(j);
if (child.getNodeType() == Node.ELEMENT_NODE) {
Element check = (Element) child;
String vaule = check.getAttribute(ATTR_VALUE);
addWhiteList(vaule);
}
}
}
}
private void addWhiteList(String item) throws IOException {
if (item.length() == 0) {
throw new IOException("Invalid config file: Missing required attribute " + ATTR_VALUE);
}
int packagePos = item.indexOf(".R.");
if (packagePos == -1) {
throw new IOException(String.format("please write the full package name,eg com.tencent.mm.R.drawable.dfdf, but yours %s\n",
item
));
}
//先去掉空格
item = item.trim();
String packageName = item.substring(0, packagePos);
//不能通过lastDot
int nextDot = item.indexOf(".", packagePos + 3);
String typeName = item.substring(packagePos + 3, nextDot);
String name = item.substring(nextDot + 1);
HashMap<String, HashSet<Pattern>> typeMap;
View on GitHub (pinned to e4df245d82)