{"record":{"id":"9e1ba5aaf19ddab4","repo":"MuntashirAkon/AppManager","slug":"ioexception-errnoexception","errorCode":null,"errorMessage":"IOException(errnoException)","messagePattern":"IOException\\(errnoException\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/LocalFile.java","lineNumber":195,"sourceCode":"    public boolean createNewLink(String existing) throws IOException {\n        return createLink(existing, false);\n    }\n\n    @Override\n    public boolean createNewSymlink(String target) throws IOException {\n        return createLink(target, true);\n    }\n\n    private boolean createLink(String target, boolean soft) throws IOException {\n        try {\n            if (soft)\n                Os.symlink(target, getPath());\n            else\n                Os.link(target, getPath());\n            return true;\n        } catch (ErrnoException e) {\n            if (e.errno != OsConstants.EEXIST) {\n                throw new IOException(e);\n            }\n            return false;\n        }\n    }\n}","sourceCodeStart":177,"sourceCodeEnd":200,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/LocalFile.java#L177-L200","documentation":"LocalFile.createLink() creates a hard link or symlink via Os.link/Os.symlink. If the OS call fails with any ErrnoException other than EEXIST, it is rethrown as an IOException wrapping the ErrnoException. EEXIST alone returns false (link already exists), but all other kernel errors (missing parent dir, permission denied, cross-device link, etc.) surface as this IOException.","triggerScenarios":"createNewLink()/createNewSymlink() when: the target file doesn't exist (ENOENT), the parent directory of the link path doesn't exist (ENOENT), the process lacks write permission on the directory (EACCES), linking across filesystems (EXDEV for hard links), or the filesystem doesn't support symlinks.","commonSituations":"Symlinking on FAT/sdcard FUSE mounts that forbid symlinks; creating links in app-external dirs without write permission; target moved/deleted between check and call; hard links across partitions.","solutions":["Check e.getCause()/errno on the IOException to identify the specific errno and fix accordingly (create parent dirs, correct target path)","Ensure both target and link location are on the same filesystem for hard links, or use a symlink instead","Verify write permission on the directory where the link is created"],"exampleFix":"// before\nnew LocalFile(dir, \"link\").createNewSymlink(target); // IOException(ErrnoException)\n// after\nFile link = new LocalFile(dir, \"link\");\nif (!link.getParentFile().exists() || !new File(target).exists()) {\n    throw new IllegalStateException(\"missing target or parent dir\");\n}\nboolean created = link.createNewSymlink(target); // returns false if already exists","handlingStrategy":"try-catch","validationCode":"File linkFile = new LocalFile(dir, name);\nif (!linkFile.getParentFile().canWrite()) throw new IOException(\"no write permission on \" + dir);\nif (!new File(target).exists()) throw new FileNotFoundException(target);","typeGuard":"boolean canCreateLinkIn(File dir, String target) { return dir.canWrite() && new File(target).exists(); }","tryCatchPattern":"try { boolean ok = file.createNewSymlink(target); } catch (IOException e) { if (e.getCause() instanceof ErrnoException) { int errno = ((ErrnoException) e.getCause()).errno; /* handle EACCES/EXDEV/ENOENT */ } }","preventionTips":["Create parent directories before linking","Use symlinks when target may be on another filesystem","Avoid symlinks on FAT/FUSE mounts that don't support them","Treat a false return as 'already exists', not failure"],"tags":["filesystem","symlink","hardlink","errno","io"],"backgroundTag":"file-write-failed","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}