{"record":{"id":"80e70f963985946d","repo":"gradle/gradle","slug":"could-not-get-file-mode-for-s","errorCode":null,"errorMessage":"Could not get file mode for '%s'.","messagePattern":"Could not get file mode for '(.+?)'\\.","errorType":"exception","errorClass":"FileException","httpStatus":null,"severity":"error","filePath":"platforms/core-runtime/native/src/main/java/org/gradle/internal/nativeintegration/filesystem/services/GenericFileSystem.java","lineNumber":104,"sourceCode":"        try {\n            symlink.symlink(link, target);\n        } catch (Exception e) {\n            throw new FileException(String.format(\"Could not create symlink from '%s' to '%s'.\", link.getPath(), target.getPath()), e);\n        }\n    }\n\n    @Override\n    public boolean isSymlink(File suspect) {\n        return symlink.isSymlink(suspect);\n    }\n\n    @Override\n    public int getUnixMode(File f) {\n        statisticsCollector.reportUnixModeQueried();\n        try {\n            return stat.getUnixMode(f);\n        } catch (Exception e) {\n            throw new FileException(String.format(\"Could not get file mode for '%s'.\", f), e);\n        }\n    }\n\n    @Override\n    public FileMetadata stat(File f) throws FileException {\n        statisticsCollector.reportFileStated();\n        return metadata.stat(f);\n    }\n\n    @Override\n    public void chmod(File f, int mode) {\n        try {\n            chmod.chmod(f, mode);\n        } catch (Exception e) {\n            throw new FileException(String.format(\"Could not set file mode %o on '%s'.\", mode, f), e);\n        }\n    }\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/core-runtime/native/src/main/java/org/gradle/internal/nativeintegration/filesystem/services/GenericFileSystem.java#L86-L122","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Guard with f.exists() when absence is expected, and treat FileException as 'file vanished' in race-prone loops","Fix directory search/execute permissions on the parent path if the cause indicates EACCES","Serialize the producer task and the consumer of getUnixMode so the file is stable when statting"],"exampleFix":"// before\nint mode = fileSystem.getUnixMode(f);\n\n// after\nint mode;\ntry {\n    mode = fileSystem.getUnixMode(f);\n} catch (FileException e) {\n    if (!f.exists()) { return; } // vanished between listing and stat\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (f.isFile() || f.isDirectory()) { // quick existence gate\n    int mode = fileSystem.getUnixMode(f);\n}","typeGuard":null,"tryCatchPattern":"try {\n    int mode = fileSystem.getUnixMode(f);\n} catch (FileException e) {\n    if (!f.exists()) {\n        return OptionalInt.empty(); // disappeared between listing and stat\n    }\n    throw e; // real stat failure: permissions etc.\n}","preventionTips":["In directory scans, stat immediately after listing and tolerate disappearance","Grant the daemon user read+execute on scanned trees to avoid EACCES-wrapped failures","Do not cache modes across task invocations; re-stat when the file may have changed"],"tags":["stat","file-mode","filesystem","race-condition"],"backgroundTag":"file-stat-failed","analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}