zxing/zxing · error · IllegalArgumentException
Invalid parent dir:
Error message
Invalid parent dir:
What it means
Thrown by StringsResourceTranslator.translate when the parent directory name of the translated (target) strings.xml file does not match the regex values-(.+). The tool is built specifically for the Android resource layout where localized files live under res/values-<locale>/strings.xml; any other directory naming is rejected. The matched group becomes the language code passed to the Google Translate API.
Source
Thrown at javase/src/main/java/com/google/zxing/client/j2se/StringsResourceTranslator.java:120
VALUES_DIR_PATTERN.matcher(entry.getFileName().toString()).matches();
try (DirectoryStream<Path> dirs = Files.newDirectoryStream(resDir, filter)) {
for (Path dir : dirs) {
translate(stringsFile, dir.resolve("strings.xml"), forceRetranslation);
}
}
}
private static void translate(Path englishFile,
Path translatedFile,
Collection<String> forceRetranslation) throws IOException {
Map<String, String> english = readLines(englishFile);
Map<String,String> translated = readLines(translatedFile);
String parentName = translatedFile.getParent().getFileName().toString();
Matcher stringsFileNameMatcher = STRINGS_FILE_NAME_PATTERN.matcher(parentName);
if (!stringsFileNameMatcher.find()) {
throw new IllegalArgumentException("Invalid parent dir: " + parentName);
}
String language = stringsFileNameMatcher.group(1);
String massagedLanguage = LANGUAGE_CODE_MASSAGINGS.get(language);
if (massagedLanguage != null) {
language = massagedLanguage;
}
System.out.println("Translating " + language);
Path resultTempFile = Files.createTempFile(null, null);
boolean anyChange = false;
try (Writer out = Files.newBufferedWriter(resultTempFile, StandardCharsets.UTF_8)) {
out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
out.write(APACHE_2_LICENSE);
out.write("<resources>\n");
for (Map.Entry<String,String> englishEntry : english.entrySet()) {View on GitHub (pinned to 19aa2d8254)
Solutions
- Ensure the target file path follows res/values-<locale>/strings.xml (e.g. res/values-fr/strings.xml) so the parent dir matches values-(.+).
- Create the proper localized values directory before running the tool and pass that path as translatedFile.
- Verify with the STRINGS_FILE_NAME_PATTERN: the parent folder name must start with 'values-'.
Example fix
// before
translate(Paths.get("res/values/strings.xml"),
Paths.get("res/fr/strings.xml"), force);
// after
translate(Paths.get("res/values/strings.xml"),
Paths.get("res/values-fr/strings.xml"), force); Defensive patterns
Strategy: validation
Validate before calling
Path parent = translatedFile.getParent();
String parentName = parent != null && parent.getFileName() != null
? parent.getFileName().toString() : "";
if (!parentName.matches("values-(.+)")) {
throw new IllegalArgumentException(
"Target dir must be values-<locale>, was: " + parentName);
} Type guard
boolean isValuesLocaleDir(Path p) {
if (p == null || p.getFileName() == null) return false;
return p.getFileName().toString().matches("values-(.+)");
} Try / catch
try {
translator.translate(englishFile, translatedFile, force);
} catch (IllegalArgumentException e) {
// parent dir was not values-<locale>; point user at the right Android folder
} Prevention
- Always target res/values-<locale>/strings.xml (e.g. values-fr).
- Validate the parent directory name with the values-(.+) pattern before calling translate.
- Do not point the tool at the default res/values/ (English) directory.
- Confirm the Android resource layout has not been restructured.
When it happens
Trigger: Calling translate(englishFile, translatedFile, forceRetranslation) where translatedFile.getParent().getFileName() is not of the form values-XX (e.g. the file sits directly under 'res/values/', or under 'res/values/', or a custom folder like 'res/strings-fr/').
Common situations: Pointing the translator at the default English res/values/ instead of a localized res/values-fr/ directory; restructuring Android resources so localized files no longer follow the values-<lang> convention; passing a temp/absolute path whose parent is not an Android values directory.
Related errors
- Addresses and types lengths differ
- Both dimensions must be greater than 0
- row lengths do not match
- illegal character encountered: {stringRepresentation.substri
- input matrix dimensions do not match
AI-assisted analysis of zxing/zxing@19aa2d8254 (2026-08-14).
Data as JSON: /api/errors/3b98292c5c7bb2c0.
Report an issue: GitHub.