shwenzhang/AndResGuard · error · PathAlreadyExists

PathAlreadyExists

Error message

PathAlreadyExists

What it means

PathAlreadyExists is thrown by AbstractDirectory.createDir when the directory being created already exists in the abstract dirs map. The library treats duplicate creation as an error rather than returning the existing directory.

Solutions

  1. Check containsDir(path) before calling createDir and reuse the existing Directory via getDir.
  2. Wrap createDir in try-catch for PathAlreadyExists and fetch the existing dir with getDir(path) in the catch block.
  3. Restructure loops so each unique path is created only once (dedupe with a Set).

Example fix

// before
Directory dir = root.createDir("res/values");
// after
Directory dir = root.containsDir("res/values")
    ? root.getDir("res/values")
    : root.createDir("res/values");
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists = dir.containsDir(path);

Try / catch

try { return dir.createDir(path); } catch (PathAlreadyExists e) { return dir.getDir(path); }

Prevention

When it happens

Trigger: Calling createDir(path) twice on the same AbstractDirectory for the same path, or calling createDir on a path that already exists in the loaded tree (e.g. res/values already loaded from the APK/zip).

Common situations: Re-running a resource-obfuscation pipeline on a directory object that already loaded all entries; looping over resource names where the same parent dir appears multiple times.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12). Data as JSON: /api/errors/c837158feaea35cd. Report an issue: GitHub.

Appendix: source

Thrown at AndResGuard-core/src/main/java/com/tencent/mm/directory/AbstractDirectory.java:139

  @Override
  public Directory getDir(String path) throws PathNotExist {
    SubPath subpath = getSubPath(path);
    if (subpath.dir != null) {
      return subpath.dir.getDir(subpath.path);
    }
    if (!getAbstractDirs().containsKey(subpath.path)) {
      throw new PathNotExist(path);
    }
    return getAbstractDirs().get(subpath.path);
  }

  @Override
  public Directory createDir(String path) throws DirectoryException {
    ParsedPath parsed = parsePath(path);
    AbstractDirectory dir;
    if (parsed.dir == null) {
      if (getAbstractDirs().containsKey(parsed.subpath)) {
        throw new PathAlreadyExists(path);
      }
      dir = createDirLocal(parsed.subpath);
      getAbstractDirs().put(parsed.subpath, dir);
      return dir;
    }

    if (getAbstractDirs().containsKey(parsed.dir)) {
      dir = getAbstractDirs().get(parsed.dir);
    } else {
      dir = createDirLocal(parsed.dir);
      getAbstractDirs().put(parsed.dir, dir);
    }
    return dir.createDir(parsed.subpath);
  }

  @Override
  public boolean removeFile(String path) {
    SubPath subpath;

View on GitHub (pinned to e4df245d82)