NationalSecurityAgency/ghidra · warning · IOException

Unable to delete temp directory: {tempDir.getAbsolutePath()}

Error message

Unable to delete temp directory: {tempDir.getAbsolutePath()}

What it means

Thrown by deleteTemporaryDirectory when tempDir.delete() returns false after all contained files have been successfully deleted. Directory.delete() only succeeds if the directory is empty and no process holds a lock on it. If another process re-created a file in the directory between the file-deletion loop and the directory deletion, or if the OS holds a handle, this fails.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/BulkSignatures.java:1055

	}

	private void deleteTemporaryDirectory(File tempDir) throws IOException {
		if (!tempDir.exists()) {
			return;
		}
		File[] listFiles = tempDir.listFiles();
		if (listFiles == null) {
			throw new IOException(
				"Could not list files in temp directory: " + tempDir.getAbsolutePath());
		}
		for (File listFile : listFiles) {
			if (!listFile.delete()) {
				throw new IOException(
					"Unable to delete temporary file: " + listFile.getAbsolutePath());
			}
		}
		if (!tempDir.delete()) {
			throw new IOException("Unable to delete temp directory: " + tempDir.getAbsolutePath());
		}
	}

	private class UpdateRepository extends IterateRepository {
		private File outdirectory;
		private String repo;
		private boolean overwrite;
		private DatabaseInformation info;
		private LSHVectorFactory vectorFactory;

		public UpdateRepository(File outdir, String rp, boolean owrite, DatabaseInformation i,
				LSHVectorFactory vFactory) {
			outdirectory = outdir;
			repo = rp;
			overwrite = owrite;
			info = i;
			vectorFactory = vFactory;
		}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure no concurrent processes use the same temp directory.
  2. Close any shells or tools that may have the directory as their working directory.
  3. Make the final directory deletion best-effort (log instead of throw) since leftover empty directories are low-impact.
  4. Use a unique temp directory name per run to avoid contention.

Example fix

// before
if (!tempDir.delete()) {
    throw new IOException("Unable to delete temp directory: " + tempDir.getAbsolutePath());
}

// after — best-effort cleanup
if (!tempDir.delete()) {
    Msg.warn(this, "Unable to delete temp directory (may be in use): " + tempDir.getAbsolutePath());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// No pre-validation can prevent this — it is a runtime concurrency issue.
// Ensure no concurrent processes use the same temp directory.
// Use unique directory names per run to avoid contention.

Type guard

// No type guard applicable — runtime filesystem state issue.

Try / catch

// Best-effort directory deletion at end of cleanup
if (!tempDir.delete()) {
    Msg.warn(this, "Could not delete temp directory: " + tempDir.getAbsolutePath() +
        " (may be in use by another process)");
    // Register for deletion on JVM exit as fallback
    tempDir.deleteOnExit();
}

Prevention

When it happens

Trigger: The directory is not empty at deletion time (a concurrent process wrote a new file); the directory itself is locked by another process (e.g., a shell with cwd inside it on Windows); permissions prevent deletion of the directory entry.

Common situations: Concurrent BSim runs sharing the same temp directory; a shell or file browser has the directory open; Windows Explorer holding a handle; another process re-populated the directory between file cleanup and directory deletion.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/23f47058b16ffe72. Report an issue: GitHub.