{"record":{"id":"c293cc3a48dedd6d","repo":"NationalSecurityAgency/ghidra","slug":"bad-xml-directory","errorCode":null,"errorMessage":"Bad xml directory","messagePattern":"Bad xml directory","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/BulkSignatures.java","lineNumber":157,"sourceCode":"\tpublic void close() {\n\t\tcloseConnection();\n\t}\n\n\t/**\n\t * Closes the current database connection.\n\t */\n\tprivate void closeConnection() {\n\t\tif (querydb != null) {\n\t\t\tquerydb.close();\n\t\t\tquerydb = null;\n\t\t}\n\t}\n\n\tprivate List<File> gatherXml(String prefix, File dir) throws IOException {\n\t\tList<File> res = new ArrayList<File>();\n\t\tFile[] listFiles = dir.listFiles();\n\t\tif (listFiles == null) {\n\t\t\tthrow new IOException(\"Bad xml directory\");\n\t\t}\n\t\tfor (File file : listFiles) {\n\t\t\tif (file.getName().startsWith(prefix)) {\n\t\t\t\tres.add(file);\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t}\n\n\tprivate void loadSignatureXml(File file, DescriptionManager manage)\n\t\t\tthrows SAXException, IOException, LSHException {\n\t\tErrorHandler handler = SpecXmlUtils.getXmlHandler();\n\t\tXmlPullParser parser = new NonThreadedXmlPullParserImpl(file, handler, false);\n\t\tmanage.restoreXml(parser, querydb.getLSHVectorFactory());\n\t}\n\n\tprotected void sendXmlToQueryServer(File dir, URL ghidraOverrideURL, String filter,\n\t\t\tTaskMonitor monitor)","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/BulkSignatures.java#L139-L175","documentation":"Thrown by BulkSignatures.gatherXml when File.listFiles() returns null. listFiles() returns null when the path is not a directory or is otherwise inaccessible, so the method cannot enumerate XML files. BulkSignatures uses this to collect signature ('sigs_*') and update ('update_*') files for ingest.","triggerScenarios":"Calling sendSignaturesToServer/sendUpdateToServer (which call gatherXml) with a dir argument that is a regular file, does not exist, or is unreadable due to permissions.","commonSituations":"Passing the XML file path instead of its containing directory; a generated-output directory was cleaned or never created; filesystem permission restrictions; path typo.","solutions":["Ensure dir is an existing, readable directory (not a file).","Create the directory before ingest if it does not yet exist.","Fix filesystem read permissions on the directory.","Pass the directory that contains the sigs_*/update_* files, not a single file."],"exampleFix":"// before\nbsim.sendSignaturesToServer(new File(\"out/sigs_0.xml\"), null, monitor);  // not a dir\n\n// after\nbsim.sendSignaturesToServer(new File(\"out\"), null, monitor);  // the directory","handlingStrategy":"validation","validationCode":"File dir = new File(path);\nif (!dir.exists() || !dir.isDirectory() || !dir.canRead()) {\n    throw new IOException(\"Not a readable directory: \" + path);\n}\nbsim.sendSignaturesToServer(dir, filter, monitor);","typeGuard":"private static boolean isReadableDir(File f) {\n    return f != null && f.exists() && f.isDirectory() && f.canRead();\n}","tryCatchPattern":null,"preventionTips":["Pass a directory, not a file, to sendSignaturesToServer/sendUpdateToServer.","Create the directory before ingest if it does not exist.","Validate readability before calling gatherXml indirectly."],"tags":["bsim","filesystem","directory","ioexception"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}