{"record":{"id":"01aaf7fe3ddaed57","repo":"MuntashirAkon/AppManager","slug":"already-exists","errorCode":null,"errorMessage":" already exists.","messagePattern":" already exists\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/io/PathImpl.java","lineNumber":449,"sourceCode":"        if (displayName == null) {\n            throw new IOException(\"Empty display name.\");\n        }\n        String[] dirNames = displayName.split(File.separator);\n        if (dirNames.length == 0) {\n            throw new IllegalArgumentException(\"Display name is empty\");\n        }\n        for (String name : dirNames) {\n            if (name.equals(\"..\")) {\n                throw new IOException(\"Could not create directories in the parent directory.\");\n            }\n        }\n        DocumentFile file = createArbitraryDirectories(documentFile, dirNames, dirNames.length - 1);\n        // Special case for the last segment\n        String lastSegment = dirNames[dirNames.length - 1];\n        Path fsRoot = VirtualFileSystem.getFsRoot(Paths.appendPathSegment(file.getUri(), lastSegment));\n        DocumentFile t = fsRoot != null ? fsRoot.documentFile : file.findFile(lastSegment);\n        if (t != null) {\n            throw new IOException(t.getUri() + \" already exists.\");\n        }\n        t = file.createDirectory(lastSegment);\n        if (t == null) {\n            throw new IOException(\"Directory\" + file.getUri() + File.separator + lastSegment + \" could not be created.\");\n        }\n        return new PathImpl(context, t);\n    }\n\n    @Nullable\n    public Path getParent() {\n        DocumentFile file = getRealDocumentFile(documentFile).getParentFile();\n        return file == null ? null : new PathImpl(context, file);\n    }\n\n    public boolean hasFile(@NonNull String displayName) {\n        return findFileInternal(documentFile, displayName) != null;\n    }\n","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/io/PathImpl.java#L431-L467","documentation":"createDirectories() checks whether the final segment already exists (via the VFS root or findFile) and throws IOException(\"<uri> already exists.\") if it does. The method only creates directories; it does not tolerate existing entries, unlike a true mkdirs/exists-ok semantic. The message includes the existing entry's URI.","triggerScenarios":"Calling createDirectories when the last path segment already exists as any entry (file or directory) at that location, e.g. a second call with the same name, or a file already occupying the name.","commonSituations":"Re-running an install/setup routine that creates fixed directories; a race where another process created the directory first; a stale file with the intended directory name left from a previous version.","solutions":["Check hasFile(lastSegment) or catch the IOException and treat \"already exists\" as success if an existing directory is acceptable.","Use findOrCreateDirectory instead of createDirectories when existence is expected.","Delete or rename the conflicting existing entry before creating.","Guard concurrent creators with app-level synchronization or a unique per-run name."],"exampleFix":"// before\npath.createDirectories(\"logs\"); // throws on second run\n// after\nif (!path.hasFile(\"logs\")) {\n    path.createDirectories(\"logs\");\n} else {\n    path.findOrCreateDirectory(\"logs\");\n}","handlingStrategy":"try-catch","validationCode":"boolean exists = path.hasFile(lastSegment);\nif (exists) { /* reuse, rename, or delete first */ }","typeGuard":null,"tryCatchPattern":"try {\n    return path.createDirectories(name);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().endsWith(\" already exists.\")) {\n        return path.findOrCreateDirectory(name); // tolerate existing\n    }\n    throw e;\n}","preventionTips":["Make creation idempotent via hasFile checks","Use unique per-run directory names for concurrent writers","Clean up stale entries from previous runs"],"tags":["android","filesystem","conflict","directory"],"backgroundTag":"file-already-exists","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}