{"record":{"id":"55fcb5b166daabac","repo":"NationalSecurityAgency/ghidra","slug":"function-list-cannot-be-null","errorCode":null,"errorMessage":"Function list cannot be null","messagePattern":"Function list cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/facade/SFOverviewInfo.java","lineNumber":43,"sourceCode":"public class SFOverviewInfo {\n\n\tpublic static final int DEFAULT_QUERIES_PER_STAGE  = 10;\t\t// Default number of separate function queries to make at one time\n\t\n\tprivate Set<FunctionSymbol> functions;\n\tprivate Program program;\n\tprivate QueryNearestVector queryNearestVector;\n\tprivate PreFilter preFilter;\n\t\n\t/**\n\t * Constructs an overview request with default parameters.\n\t * @param functions required--a set of functions (at least one) for which an overview will be \n\t * \t\t\t\t\tcomputed.  All functions must be from the same program.\n\t * @throws IllegalArgumentException if {@code functions} is {@code null}/empty or functions\n\t * are from multiple programs.  \n\t */\n\tpublic SFOverviewInfo(Set<FunctionSymbol> functions) {\n\t\tif (functions == null)\n\t\t\tthrow new IllegalArgumentException(\"Function list cannot be null\");\n\t\tif (functions.isEmpty())\n\t\t\tthrow new IllegalArgumentException(\"Function list cannot be empty\");\n\t\t\n\t\tthis.functions = functions;\n\t\tfor (FunctionSymbol s : functions) {\n\t\t\tif (program == null) {\n\t\t\t\tprogram = s.getProgram();\n\t\t\t}\n\t\t\telse if (program != s.getProgram()) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"all function symbols are not from the same program\");\n\t\t\t}\n\t\t}\n\t\tqueryNearestVector = new QueryNearestVector();\n\t\tpreFilter = new PreFilter();\n\t}\n\t\n\t/**","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/facade/SFOverviewInfo.java#L25-L61","documentation":"Thrown by the SFOverviewInfo constructor when the Set<FunctionSymbol> functions argument is null. SFOverviewInfo packages an overview (similarity overview, not full results) request; it requires at least one function symbol so the facade can compute signatures. This is the first of three ordered validations (null, then empty, then cross-program).","triggerScenarios":"new SFOverviewInfo(null); or passing a variable that was never assigned a non-null set (e.g. an empty selection result returned null).","commonSituations":"A plugin/dialog builds the set from the current selection and forwards it without checking when nothing is selected; refactoring that left a code path unable to populate the set.","solutions":["Null-check the selection before constructing SFOverviewInfo and abort the overview action with a user message when no functions are selected.","Use Collections.emptySet() semantics upstream so null never reaches the constructor, then let the 'cannot be empty' check carry the message.","Add Objects.requireNonNull(functions, \"functions\") at the call site for a clearer NPE if null truly indicates a bug."],"exampleFix":"// before\nSFOverviewInfo info = new SFOverviewInfo(selected);\n// after\nif (selected == null || selected.isEmpty()) {\n    popup(\"Select at least one function first\");\n    return;\n}\nSFOverviewInfo info = new SFOverviewInfo(selected);","handlingStrategy":"validation","validationCode":"if (functions == null || functions.isEmpty()) {\n    popup(\"Select at least one function first\");\n    return;\n}\nSFOverviewInfo info = new SFOverviewInfo(functions);","typeGuard":"static boolean hasOverviewInput(Set<FunctionSymbol> fns) {\n    return fns != null && !fns.isEmpty();\n}","tryCatchPattern":"try {\n    new SFOverviewInfo(functions);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"null\")) { /* prompt user to select */ }\n}","preventionTips":["Treat selection gathering as the validation boundary for null/empty.","Never pass through an unassigned set; prefer Collections.emptySet() and handle emptiness upstream.","Disable overview actions when selection is empty."],"tags":["bsim","facade","validation","argument-error","overview"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}