{"record":{"id":"1060a7b91496ef49","repo":"NationalSecurityAgency/ghidra","slug":"must-set-address-factory-first","errorCode":null,"errorMessage":"Must set address factory first.","messagePattern":"Must set address factory first\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/model/GAddressRangeField.java","lineNumber":180,"sourceCode":"\tprotected void minFocusLost(FocusEvent e) {\n\t\tif (factory == null) {\n\t\t\treturn;\n\t\t}\n\t\trevalidateMin();\n\t\tadjustMaxToMin();\n\t}\n\n\tprotected void maxFocusLost(FocusEvent e) {\n\t\tif (factory == null) {\n\t\t\treturn;\n\t\t}\n\t\trevalidateMax();\n\t\tadjustMinToMax();\n\t}\n\n\tpublic void setRange(AddressRange range) {\n\t\tif (factory == null) {\n\t\t\tthrow new IllegalStateException(\"Must set address factory first.\");\n\t\t}\n\t\tif (!List.of(factory.getAddressSpaces()).contains(range.getAddressSpace())) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\"Given range's space must be in the factory's physical spaces\");\n\t\t}\n\t\tfieldSpace.setSelectedItem(range.getAddressSpace().getName());\n\t\tfieldMin.setText(Long.toUnsignedString(range.getMinAddress().getOffset(), 16));\n\t\tfieldMax.setText(Long.toUnsignedString(range.getMaxAddress().getOffset(), 16));\n\t}\n\n\tpublic AddressRange getRange() {\n\t\tString name = (String) fieldSpace.getSelectedItem();\n\t\tif (name == null) {\n\t\t\treturn null;\n\t\t}\n\t\tAddressSpace space = Objects.requireNonNull(factory.getAddressSpace(name));\n\t\tlong min = Long.parseUnsignedLong(fieldMin.getText(), 16);\n\t\tlong max = Long.parseUnsignedLong(fieldMax.getText(), 16);","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/model/GAddressRangeField.java#L162-L198","documentation":"GAddressRangeField.setRange requires that an AddressFactory has been set on the field component before a range can be assigned. The factory defines the address spaces and parsing rules needed to validate and display the range. Without it, the component cannot interpret any address or space. This is an IllegalStateException (not IllegalArgumentException) because it indicates the component was used before completing its initialization sequence.","triggerScenarios":"Calling setRange(range) on a GAddressRangeField instance before calling setFactory(factory). The factory field is null and the guard at line 179 detects this.","commonSituations":"Building a UI dialog or panel that constructs the field and immediately sets a range in the constructor before the factory is wired. Using a field from a reused component where the factory was cleared. Initializing fields in the wrong order during panel setup.","solutions":["Call setFactory(factory) before setRange(range)","Set the factory in the panel/dialog initialization method before any range operations","Use a builder or initialization helper that enforces the factory-first ordering","If unsure whether the factory is set, guard: if (field.getFactory() != null) field.setRange(range)"],"exampleFix":"// before\nGAddressRangeField field = new GAddressRangeField();\nfield.setRange(range); // throws: no factory\n// after\nGAddressRangeField field = new GAddressRangeField();\nfield.setFactory(addressFactory);\nfield.setRange(range);","handlingStrategy":"validation","validationCode":"boolean isFieldInitialized(GAddressRangeField field) {\n    // Check factory is set before calling setRange\n    return field.getFactory() != null;\n}\n\n// Guarded call:\nif (field.getFactory() != null) {\n    field.setRange(range);\n}","typeGuard":"// N/A — GAddressRangeField is a single type; check initialization state","tryCatchPattern":"try {\n    field.setRange(range);\n} catch (IllegalStateException e) {\n    field.setFactory(factory);\n    field.setRange(range);\n}","preventionTips":["Always call setFactory before setRange in panel/dialog initialization","Order initialization: factory first, then ranges","Use a builder pattern or init helper that enforces ordering"],"tags":["ghidra","ui","address-range","initialization","precondition"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}