MuntashirAkon/AppManager · error
IOException(errnoException)
Error message
IOException(errnoException)
What it means
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.
Source
Thrown at libcore/io/src/main/java/io/github/muntashirakon/io/LocalFile.java:195
public boolean createNewLink(String existing) throws IOException {
return createLink(existing, false);
}
@Override
public boolean createNewSymlink(String target) throws IOException {
return createLink(target, true);
}
private boolean createLink(String target, boolean soft) throws IOException {
try {
if (soft)
Os.symlink(target, getPath());
else
Os.link(target, getPath());
return true;
} catch (ErrnoException e) {
if (e.errno != OsConstants.EEXIST) {
throw new IOException(e);
}
return false;
}
}
}View on GitHub (pinned to 0152f468fc)
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
Example fix
// before
new LocalFile(dir, "link").createNewSymlink(target); // IOException(ErrnoException)
// after
File link = new LocalFile(dir, "link");
if (!link.getParentFile().exists() || !new File(target).exists()) {
throw new IllegalStateException("missing target or parent dir");
}
boolean created = link.createNewSymlink(target); // returns false if already exists Defensive patterns
Strategy: try-catch
Validate before calling
File linkFile = new LocalFile(dir, name);
if (!linkFile.getParentFile().canWrite()) throw new IOException("no write permission on " + dir);
if (!new File(target).exists()) throw new FileNotFoundException(target); Type guard
boolean canCreateLinkIn(File dir, String target) { return dir.canWrite() && new File(target).exists(); } Try / catch
try { boolean ok = file.createNewSymlink(target); } catch (IOException e) { if (e.getCause() instanceof ErrnoException) { int errno = ((ErrnoException) e.getCause()).errno; /* handle EACCES/EXDEV/ENOENT */ } } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Could not get backup files.
- Could not get backup files
- Could not create cache. Is this OS broken?
- Couldn't create symbolic link ${file} pointing to ${linkName
- EBADF
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/9e1ba5aaf19ddab4.
Report an issue: GitHub.