{"record":{"id":"b89f95bfbdf1c158","repo":"shwenzhang/AndResGuard","slug":"can-not-found-res-dir-in-the-apk-or-it-is-not-a-dir","errorCode":null,"errorMessage":"can not found res dir in the apk or it is not a dir","messagePattern":"can not found res dir in the apk or it is not a dir","errorType":"exception","errorClass":"java.io.IOException","httpStatus":null,"severity":"error","filePath":"AndResGuard-core/src/main/java/com/tencent/mm/androlib/ApkDecoder.java","lineNumber":106,"sourceCode":"    if (!config.mKeepRoot) {\n      mOutResFile = new File(mOutDir.getAbsolutePath() + File.separator + TypedValue.RES_FILE_PATH);\n    } else {\n      mOutResFile = new File(mOutDir.getAbsolutePath() + File.separator + \"res\");\n    }\n\n    //这个需要混淆各个文件夹\n    mRawResFile = new File(mOutDir.getAbsoluteFile().getAbsolutePath()\n                           + File.separator\n                           + TypedValue.UNZIP_FILE_PATH\n                           + File.separator\n                           + \"res\");\n    mOutTempDir = new File(mOutDir.getAbsoluteFile().getAbsolutePath() + File.separator + TypedValue.UNZIP_FILE_PATH);\n\n    //这里纪录原始res目录的文件\n    Files.walkFileTree(mRawResFile.toPath(), new ResourceFilesVisitor());\n\n    if (!mRawResFile.exists() || !mRawResFile.isDirectory()) {\n      throw new IOException(\"can not found res dir in the apk or it is not a dir\");\n    }\n\n    mOutTempARSCFile = new File(mOutDir.getAbsoluteFile().getAbsolutePath() + File.separator + \"resources_temp.arsc\");\n    mOutARSCFile = new File(mOutDir.getAbsoluteFile().getAbsolutePath() + File.separator + \"resources.arsc\");\n\n    String basename = apkFile.getName().substring(0, apkFile.getName().indexOf(\".apk\"));\n    mResMappingFile = new File(mOutDir.getAbsoluteFile().getAbsolutePath()\n                               + File.separator\n                               + TypedValue.RES_MAPPING_FILE\n                               + basename\n                               + TypedValue.TXT_FILE);\n    mMergeDuplicatedResMappingFile = new File(mOutDir.getAbsoluteFile().getAbsolutePath()\n                             + File.separator\n                             + TypedValue.MERGE_DUPLICATED_RES_MAPPING_FILE\n                             + basename\n                             + TypedValue.TXT_FILE);\n  }\n","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/com/tencent/mm/androlib/ApkDecoder.java#L88-L124","documentation":"AndResGuard unzips the APK and expects an Android resource directory named 'res' inside it. This IOException is thrown when the extracted 'res' directory cannot be found or the path exists but is not a directory, meaning the input APK has no standard resources folder to process.","triggerScenarios":"Running AndResGuard's decode() on an APK whose extracted output has no res/ directory (mRawResFile missing) or where res exists as a regular file rather than a directory.","commonSituations":"Input file is not actually an APK (e.g. an AAB, a XAPK/zip of APKs, a corrupted download); the APK was built without resources; or a previous partial run left a broken unzip output in the output directory.","solutions":["Verify the input file is a valid APK containing a res/ directory: unzip -l app.apk | grep ' res/'","If you have an .aab, build an APK (bundletool build-apks / assembleRelease) instead of feeding the AAB to AndResGuard","Clean the output directory to remove stale/partial UNZIP_FILE_PATH output from a previous failed run","Re-download or rebuild the APK if it is corrupt or truncated"],"exampleFix":"// before\njava -jar andresguard.jar input.xapk\n// after\nbundletool build-apks --bundle=input.aab --output=app.apks\n# extract the universal.apk and pass that to AndResGuard","handlingStrategy":"validation","validationCode":"import java.util.zip.ZipFile;\nstatic boolean apkHasResDir(File apk) {\n  if (apk == null || !apk.isFile()) return false;\n  try (ZipFile zf = new ZipFile(apk)) {\n    return zf.getEntry(\"res/\") != null && zf.getEntry(\"res/\").isDirectory();\n  } catch (IOException e) { return false; }\n}\nif (!apkHasResDir(inputApk)) throw new IllegalArgumentException(\"input is not an APK with res/: \" + inputApk);","typeGuard":"static boolean isApkWithRes(File f) {\n  return f != null && f.isFile() && f.length() > 0 && f.getName().endsWith(\".apk\");\n}","tryCatchPattern":null,"preventionTips":["Sanity-check inputs with 'unzip -l | grep res/' before running AndResGuard","Always feed an APK, never an .aab, .xapk, or split-APK bundle","Clean the output directory between runs to avoid stale unzip artifacts"],"tags":["android","apk","resource-not-found","build"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"e4df245d82f27d9a2d0dd108260a3510cbaba849","analyzedAt":"2026-09-12T17:49:07.798Z","contentChangedAt":"2026-09-12T17:49:07.798Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}