{"record":{"id":"3d277f8c3726a0ee","repo":"MuntashirAkon/AppManager","slug":"is-a-directory","errorCode":null,"errorMessage":" is a directory","messagePattern":" is a directory","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/io/PathImpl.java","lineNumber":1206,"sourceCode":"                    throw (FileNotFoundException) new FileNotFoundException(\"Could not open file \" + file).initCause(e);\n                }\n            } // else use the default content provider\n        } else if (documentFile instanceof VirtualDocumentFile) {\n            int modeBits = ParcelFileDescriptor.parseMode(mode);\n            try {\n                return ((VirtualDocumentFile) documentFile).openFileDescriptor(modeBits);\n            } catch (IOException e) {\n                throw (FileNotFoundException) new FileNotFoundException(e.getMessage()).initCause(e);\n            }\n        }\n        return FileUtils.getFdFromUri(context, documentFile.getUri(), mode);\n    }\n\n    @NonNull\n    public OutputStream openOutputStream(boolean append) throws IOException {\n        DocumentFile documentFile = resolveFileOrNull(this.documentFile);\n        if (documentFile == null) {\n            throw new IOException(this.documentFile.getUri() + \" is a directory\");\n        }\n        if (documentFile instanceof ExtendedRawDocumentFile) {\n            try {\n                return Objects.requireNonNull(getFile()).newOutputStream(append);\n            } catch (IOException e) {\n                throw new IOException(\"Could not open file for writing: \" + documentFile.getUri(), e);\n            }\n        } else if (documentFile instanceof VirtualDocumentFile) {\n            return ((VirtualDocumentFile) documentFile).openOutputStream(append);\n        }\n        String mode = \"w\" + (append ? \"a\" : \"t\");\n        OutputStream os = context.getContentResolver().openOutputStream(documentFile.getUri(), mode);\n        if (os == null) {\n            throw new IOException(\"Could not resolve Uri: \" + documentFile.getUri());\n        }\n        return os;\n    }\n","sourceCodeStart":1188,"sourceCodeEnd":1224,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/io/PathImpl.java#L1188-L1224","documentation":"openOutputStream(append) calls resolveFileOrNull(this.documentFile); when resolution yields null the underlying document is (or resolves to) a directory, and the method throws IOException(uri + \" is a directory\"). Directories have no byte stream, so opening an output stream on them is meaningless.","triggerScenarios":"Calling path.openOutputStream()/openOutputStream(true) on a Path whose document is a directory (resolveFileOrNull returns null), e.g. a directory URI or a path that got resolved to a directory.","commonSituations":"Using a user-picked SAF tree/document URI that points at a folder, iterating entries without filtering out directories, or path construction that accidentally selects a directory.","solutions":["Check path.isDirectory() before opening a stream","Call getUri()/lastPathSegment checks or list files and open streams only on files","Resolve to the intended child file inside the directory first"],"exampleFix":"// before\nOutputStream os = path.openOutputStream();\n// after\nif (path.isDirectory()) throw new IllegalArgumentException(\"Expected a file: \" + path.getUri());\nOutputStream os = path.openOutputStream();","handlingStrategy":"validation","validationCode":"if (path.isDirectory()) {\n    throw new IllegalArgumentException(\"Cannot open output stream on a directory\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    OutputStream os = path.openOutputStream(append);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().endsWith(\" is a directory\")) {\n        // resolve to the intended child file and retry\n    } else throw e;\n}","preventionTips":["Always isDirectory()-check before stream APIs","Filter listFiles() results to files before reading/writing","Treat SAF tree URIs as directories unless resolved to a document"],"tags":["io","android","documentfile","stream"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}