peass-ng/PEASS-ng · error · IOException
The target directory is a file, not a directory: [{0}]
Error message
The target directory is a file, not a directory: [{0}] What it means
DeleteEmptySubdirectoriesCore throws IOException with message 'The target directory is a file, not a directory: [{0}]' when the fsEntryInfo resolved from the given path reports IsDirectory == false. DeleteEmptySubdirectories only makes sense on directories, so AlphaFS fails fast with this explicit message rather than letting the native layer return a generic error.
Source
Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/Directory Class/Directory Core Methods/Directory.DeleteEmptySubdirectoriesCore.cs:71
{
if (pathFormat == PathFormat.RelativePath)
Path.CheckSupportedPathFormat(path, true, true);
if (!File.ExistsCore(transaction, true, path, pathFormat))
NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, path);
fsEntryInfo = File.GetFileSystemEntryInfoCore(transaction, true, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck), false, pathFormat);
if (null == fsEntryInfo)
return;
}
#endregion // Setup
// Ensure path is a directory.
if (!fsEntryInfo.IsDirectory)
throw new IOException(string.Format(CultureInfo.InvariantCulture, Resources.Target_Directory_Is_A_File, fsEntryInfo.LongFullPath));
var dirs = new Stack<string>(1000);
dirs.Push(fsEntryInfo.LongFullPath);
while (dirs.Count > 0)
{
foreach (var fsei in EnumerateFileSystemEntryInfosCore<FileSystemEntryInfo>(true, transaction, dirs.Pop(), Path.WildcardStarMatchAll, null, DirectoryEnumerationOptions.ContinueOnException, null, PathFormat.LongFullPath))
{
// Ensure the directory is empty.
if (IsEmptyCore(transaction, fsei.LongFullPath, pathFormat))
DeleteDirectoryCore(transaction, fsei, null, false, ignoreReadOnly, true, PathFormat.LongFullPath);
else if (recursive)
dirs.Push(fsei.LongFullPath);
}
}
}View on GitHub (pinned to 53fb989abc)
Solutions
- Check Directory.Exists(path) and that it is not a file (File.Exists) before calling.
- Inspect FileSystemEntryInfo.IsDirectory via File.GetFileSystemEntryInfo before invoking.
- Filter your path list to directories only using Directory.GetFileSystemEntries / attributes.
- Catch IOException and log/skip non-directory entries in batch cleanup loops.
Example fix
// before
Directory.DeleteEmptySubdirectories(p); // p may be a file
// after
var info = File.GetFileSystemEntryInfo(p);
if (info != null && info.IsDirectory)
Directory.DeleteEmptySubdirectories(p); Defensive patterns
Strategy: validation
Validate before calling
var info = File.GetFileSystemEntryInfo(path);
if (info == null || !info.IsDirectory)
throw new InvalidOperationException($"{path} is not a directory"); Type guard
bool IsDirectoryEntry(FileSystemEntryInfo e) => e != null && e.IsDirectory;
Try / catch
try { Directory.DeleteEmptySubdirectories(path); }
catch (IOException ex) when (ex.Message.Contains("is a file")) { logger.LogWarning("Skipping non-directory {Path}", path); } Prevention
- Filter path lists to directories before batch cleanup
- Check IsDirectory on FileSystemEntryInfo before directory-only operations
- Handle entries being replaced by files concurrently (re-check late)
- Log and skip rather than abort whole cleanup runs on type mismatches
When it happens
Trigger: Calling Directory.DeleteEmptySubdirectories / DeleteEmptySubdirectoriesTransacted with a path that points to a regular file; a reparse point/symlink that resolves to a file; stale path captured before the directory was replaced by a file.
Common situations: Automated cleanup jobs iterating a list of paths where some entries are files; configuration/user input supplying a file path; a race where another process swapped the directory for a file between enumeration and the call.
Related errors
- ({0}) The target directory is a file, not a directory: [{1}]
- ERROR_DIR_NOT_EMPTY
- ERROR_ALREADY_EXISTS
- ERROR_DIR_NOT_EMPTY
- ERROR_FILE_READ_ONLY
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/ea6010f5c82e5b4b.
Report an issue: GitHub.