gradle/gradle · error · FileException

Could not get file mode for '%s'.

Error message

Could not get file mode for '%s'.

What it means

GenericFileSystem.getUnixMode reports usage statistics then delegates to the bound FileModeAccessor (native stat or FallbackStat), wrapping any exception into FileException. With FallbackStat the cause is typically FileNotFoundException for a missing path; with native stat it mirrors errno from stat(2).

Source

Thrown at platforms/core-runtime/native/src/main/java/org/gradle/internal/nativeintegration/filesystem/services/GenericFileSystem.java:104

        try {
            symlink.symlink(link, target);
        } catch (Exception e) {
            throw new FileException(String.format("Could not create symlink from '%s' to '%s'.", link.getPath(), target.getPath()), e);
        }
    }

    @Override
    public boolean isSymlink(File suspect) {
        return symlink.isSymlink(suspect);
    }

    @Override
    public int getUnixMode(File f) {
        statisticsCollector.reportUnixModeQueried();
        try {
            return stat.getUnixMode(f);
        } catch (Exception e) {
            throw new FileException(String.format("Could not get file mode for '%s'.", f), e);
        }
    }

    @Override
    public FileMetadata stat(File f) throws FileException {
        statisticsCollector.reportFileStated();
        return metadata.stat(f);
    }

    @Override
    public void chmod(File f, int mode) {
        try {
            chmod.chmod(f, mode);
        } catch (Exception e) {
            throw new FileException(String.format("Could not set file mode %o on '%s'.", mode, f), e);
        }
    }

View on GitHub (pinned to 534f27719b)

Solutions

  1. Guard with f.exists() when absence is expected, and treat FileException as 'file vanished' in race-prone loops
  2. Fix directory search/execute permissions on the parent path if the cause indicates EACCES
  3. Serialize the producer task and the consumer of getUnixMode so the file is stable when statting

Example fix

// before
int mode = fileSystem.getUnixMode(f);

// after
int mode;
try {
    mode = fileSystem.getUnixMode(f);
} catch (FileException e) {
    if (!f.exists()) { return; } // vanished between listing and stat
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (f.isFile() || f.isDirectory()) { // quick existence gate
    int mode = fileSystem.getUnixMode(f);
}

Try / catch

try {
    int mode = fileSystem.getUnixMode(f);
} catch (FileException e) {
    if (!f.exists()) {
        return OptionalInt.empty(); // disappeared between listing and stat
    }
    throw e; // real stat failure: permissions etc.
}

Prevention

When it happens

Trigger: FileSystem.getUnixMode(f) on a file deleted between discovery and stat (TOCTOU race), a path with an unreadable parent directory, or any stat failure raised by the underlying accessor.

Common situations: VFS/incremental-build scanners racing a clean task; build logic statting outputs of a parallel task; querying modes inside a directory the daemon user cannot traverse.

Related errors


AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22). Data as JSON: /api/errors/80e70f963985946d. Report an issue: GitHub.