{"record":{"id":"5d6789e7d30fc10f","repo":"NationalSecurityAgency/ghidra","slug":"could-not-list-files-in-temp-directory-tempdir-g","errorCode":null,"errorMessage":"Could not list files in temp directory: {tempDir.getAbsolutePath()}","messagePattern":"Could not list files in temp directory: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/BulkSignatures.java","lineNumber":1045,"sourceCode":"\t\tif (dir.exists() == false) {\n\t\t\tif (dir.mkdir() == false) {\n\t\t\t\tthrow new IOException(\"Unable to create temp directory: \" + dir.getAbsolutePath());\n\t\t\t}\n\t\t}\n\t\telse if (dir.isDirectory() == false) {\n\t\t\tthrow new IOException(dir.getAbsolutePath() + \": is not a directory\");\n\t\t}\n\t\tdir = dir.getCanonicalFile();\n\t\treturn dir;\n\t}\n\n\tprivate void deleteTemporaryDirectory(File tempDir) throws IOException {\n\t\tif (!tempDir.exists()) {\n\t\t\treturn;\n\t\t}\n\t\tFile[] listFiles = tempDir.listFiles();\n\t\tif (listFiles == null) {\n\t\t\tthrow new IOException(\n\t\t\t\t\"Could not list files in temp directory: \" + tempDir.getAbsolutePath());\n\t\t}\n\t\tfor (File listFile : listFiles) {\n\t\t\tif (!listFile.delete()) {\n\t\t\t\tthrow new IOException(\n\t\t\t\t\t\"Unable to delete temporary file: \" + listFile.getAbsolutePath());\n\t\t\t}\n\t\t}\n\t\tif (!tempDir.delete()) {\n\t\t\tthrow new IOException(\"Unable to delete temp directory: \" + tempDir.getAbsolutePath());\n\t\t}\n\t}\n\n\tprivate class UpdateRepository extends IterateRepository {\n\t\tprivate File outdirectory;\n\t\tprivate String repo;\n\t\tprivate boolean overwrite;\n\t\tprivate DatabaseInformation info;","sourceCodeStart":1027,"sourceCodeEnd":1063,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/BulkSignatures.java#L1027-L1063","documentation":"Thrown by deleteTemporaryDirectory when tempDir.listFiles() returns null. File.listFiles() returns null when the path is not a directory or when an I/O error occurs during listing. Since deleteTemporaryDirectory already checked tempDir.exists(), the most likely cause is a permission issue preventing directory enumeration, or the path was removed by another process between the exists check and the listFiles call.","triggerScenarios":"Calling deleteTemporaryDirectory on a path that exists but cannot be listed due to OS-level permission denial (no execute/read permission on the directory); a race condition where the directory is deleted by another process between the exists() and listFiles() calls; the path became a non-directory between checks.","commonSituations":"Running as a different user than the one that created the temp directory; SELinux or AppArmor blocking directory enumeration; a concurrent BSim run cleaning up the same temp directory; filesystem corruption on the temp volume.","solutions":["Check directory permissions (read + execute on the directory) for the current user.","Use try-catch around deleteTemporaryDirectory and log the path — in cleanup contexts, best-effort deletion is often acceptable.","Ensure only one BSim process uses the same temp directory at a time.","Run with appropriate user privileges matching the process that created the temp files."],"exampleFix":"// before\nFile[] listFiles = tempDir.listFiles();\nif (listFiles == null) {\n    throw new IOException(\"Could not list files in temp directory: \" + tempDir.getAbsolutePath());\n}\n\n// after — best-effort cleanup with fallback\nFile[] listFiles = tempDir.listFiles();\nif (listFiles == null) {\n    if (!tempDir.delete()) {\n        Msg.warn(this, \"Could not list or delete temp directory: \" + tempDir.getAbsolutePath());\n    }\n    return;\n}","handlingStrategy":"validation","validationCode":"// Check directory readability before attempting to list files\nif (tempDir == null || !tempDir.exists()) {\n    return; // nothing to clean\n}\nif (!tempDir.isDirectory()) {\n    throw new IllegalStateException(\"Not a directory: \" + tempDir.getAbsolutePath());\n}\nif (!tempDir.canRead()) {\n    // Cannot enumerate — skip cleanup with a warning\n    return;\n}","typeGuard":"public static boolean isListableDirectory(File dir) {\n    return dir != null && dir.isDirectory() && dir.canRead();\n}","tryCatchPattern":"// Cleanup is best-effort — wrap in try-catch and continue\ntry {\n    deleteTemporaryDirectory(tempDir);\n} catch (IOException e) {\n    // Log and continue — leftover temp files are non-fatal\n    Msg.warn(BulkSignatures.class, \"Temp cleanup failed: \" + e.getMessage());\n}","preventionTips":["Treat temp directory cleanup as best-effort — log failures instead of aborting.","Ensure directory permissions allow enumeration by the cleanup process.","Avoid concurrent processes sharing the same temp directory.","Run cleanup with the same user that created the temp files."],"tags":["bsim","file-io","temp-directory","cleanup","permissions"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}