SonarSource/sonarqube · error · IOException
Directory '%s' is a file
Error message
Directory '%s' is a file
What it means
FileUtils2.deleteDirectory throws this IOException when the given File exists but is a regular file rather than a directory. The guard exists so callers get a clear message instead of a confusing failure from the recursive delete walk.
Source
Thrown at server/sonar-process/src/main/java/org/sonar/process/FileUtils2.java:119
/**
* Deletes a directory recursively. Does not support symbolic link to directories.
*
* @param directory directory to delete
* @throws IOException in case deletion is unsuccessful
*/
public static void deleteDirectory(File directory) throws IOException {
requireNonNull(directory, DIRECTORY_CAN_NOT_BE_NULL);
if (!directory.exists()) {
return;
}
Path path = directory.toPath();
if (Files.isSymbolicLink(path)) {
throw new IOException(format("Directory '%s' is a symbolic link", directory));
}
if (directory.isFile()) {
throw new IOException(format("Directory '%s' is a file", directory));
}
deleteDirectoryImpl(path);
}
/**
* Size of file or directory, in bytes. In case of a directory,
* the size is the sum of the sizes of all files recursively traversed.
*
* This implementation is recommended over commons-io
* {@code FileUtils#sizeOf(File)} which suffers from slow usage of Java IO.
*
* @throws IOException if files can't be traversed or size attribute is not present
* @see BasicFileAttributes#size()
*/
public static long sizeOf(Path path) throws IOException {
SizeVisitor visitor = new SizeVisitor();
Files.walkFileTree(path, visitor);
return visitor.size;View on GitHub (pinned to 184c821202)
Solutions
- Check File.isDirectory() before calling deleteDirectory and delete the file with File.delete() instead
- Verify the path configured actually points to a directory
- Delete the file manually and retry
Example fix
// before
FileUtils2.deleteDirectory(target);
// after
if (target.isFile()) {
target.delete();
} else {
FileUtils2.deleteDirectory(target);
} Defensive patterns
Strategy: validation
Validate before calling
if (!new File(path).isDirectory()) { throw new IllegalArgumentException(path + " is not a directory"); }
FileUtils2.deleteDirectory(new File(path)); Try / catch
try { FileUtils2.deleteDirectory(dir); } catch (IOException e) { if (e.getMessage().contains("is a file")) { /* handle file-vs-dir */ } else throw e; } Prevention
- Always check File.isDirectory() before directory operations
- Validate configured paths at startup
- Never assume a path's type from its name or extension
When it happens
Trigger: Calling FileUtils2.deleteDirectory(new File(path)) where path points to a regular file, not a directory (and is not a symlink).
Common situations: Path built from config/env with wrong trailing component; a file replaced a directory between planning and execution; code assumes extension implies directory.
Related errors
- Failed to create directory %s
- '%s' is not a directory
- Can not write to file
- Can not delete
- Can not move file to
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/3cfcfc28d0aa4b7e.
Report an issue: GitHub.