{"record":{"id":"3b98292c5c7bb2c0","repo":"zxing/zxing","slug":"invalid-parent-dir","errorCode":null,"errorMessage":"Invalid parent dir: ","messagePattern":"Invalid parent dir: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"javase/src/main/java/com/google/zxing/client/j2se/StringsResourceTranslator.java","lineNumber":120,"sourceCode":"        VALUES_DIR_PATTERN.matcher(entry.getFileName().toString()).matches();\n    try (DirectoryStream<Path> dirs = Files.newDirectoryStream(resDir, filter)) {\n      for (Path dir : dirs) {\n        translate(stringsFile, dir.resolve(\"strings.xml\"), forceRetranslation);\n      }\n    }\n  }\n\n  private static void translate(Path englishFile,\n                                Path translatedFile,\n                                Collection<String> forceRetranslation) throws IOException {\n\n    Map<String, String> english = readLines(englishFile);\n    Map<String,String> translated = readLines(translatedFile);\n    String parentName = translatedFile.getParent().getFileName().toString();\n\n    Matcher stringsFileNameMatcher = STRINGS_FILE_NAME_PATTERN.matcher(parentName);\n    if (!stringsFileNameMatcher.find()) {\n      throw new IllegalArgumentException(\"Invalid parent dir: \" + parentName);\n    }\n    String language = stringsFileNameMatcher.group(1);\n    String massagedLanguage = LANGUAGE_CODE_MASSAGINGS.get(language);\n    if (massagedLanguage != null) {\n      language = massagedLanguage;\n    }\n\n    System.out.println(\"Translating \" + language);\n\n    Path resultTempFile = Files.createTempFile(null, null);\n\n    boolean anyChange = false;\n    try (Writer out = Files.newBufferedWriter(resultTempFile, StandardCharsets.UTF_8)) {\n      out.write(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\");\n      out.write(APACHE_2_LICENSE);\n      out.write(\"<resources>\\n\");\n\n      for (Map.Entry<String,String> englishEntry : english.entrySet()) {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/zxing/zxing/blob/19aa2d8254410e161f04dc3c928e68d5e90233c2/javase/src/main/java/com/google/zxing/client/j2se/StringsResourceTranslator.java#L102-L138","documentation":"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.","triggerScenarios":"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/').","commonSituations":"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.","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-'."],"exampleFix":"// before\ntranslate(Paths.get(\"res/values/strings.xml\"),\n         Paths.get(\"res/fr/strings.xml\"), force);\n\n// after\ntranslate(Paths.get(\"res/values/strings.xml\"),\n         Paths.get(\"res/values-fr/strings.xml\"), force);","handlingStrategy":"validation","validationCode":"Path parent = translatedFile.getParent();\nString parentName = parent != null && parent.getFileName() != null\n    ? parent.getFileName().toString() : \"\";\nif (!parentName.matches(\"values-(.+)\")) {\n  throw new IllegalArgumentException(\n    \"Target dir must be values-<locale>, was: \" + parentName);\n}","typeGuard":"boolean isValuesLocaleDir(Path p) {\n  if (p == null || p.getFileName() == null) return false;\n  return p.getFileName().toString().matches(\"values-(.+)\");\n}","tryCatchPattern":"try {\n  translator.translate(englishFile, translatedFile, force);\n} catch (IllegalArgumentException e) {\n  // parent dir was not values-<locale>; point user at the right Android folder\n}","preventionTips":["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."],"tags":["zxing","i18n","android","validation","path"],"backgroundTag":null,"analyzedSha":"19aa2d8254410e161f04dc3c928e68d5e90233c2","analyzedAt":"2026-08-14T03:07:53.428Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}