NationalSecurityAgency/ghidra · error · IllegalArgumentException
Unsupported command: {}
Error message
Unsupported command: {} What it means
Thrown inside readOptions() when ALLOWED_OPTION_MAP.get(command) returns null. Because run() already validated the command against COMMAND_SET before calling readOptions(), and all 18 registered commands have entries in ALLOWED_OPTION_MAP, this is a defensive guard that indicates a programming bug: a developer registered a new command via defineCommand() but forgot to add its entry to ALLOWED_OPTION_MAP in the static initializer.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/BSimLaunchable.java:296
else if (ghidraURLString != null) {
bsimURL = BSimClientFactory.deriveBSimURL(ghidraURLString);
}
}
/**
* Read in any optional parameters, strip them from the parameter stream
* @param command command name
* @param params is the original array of command line parameters
* @param discard number of params already consumed
* @return an array of parameters with optional ones stripped
*/
private List<String> readOptions(String command, String[] params, int discard) {
boolean sawOptions = false;
Set<String> allowedParams = ALLOWED_OPTION_MAP.get(command);
if (allowedParams == null) {
throw new IllegalArgumentException("Unsupported command: " + command);
}
List<String> subParams = new ArrayList<String>();
for (int i = discard; i < params.length; ++i) {
String optionName = params[i];
String value = null;
if (optionName.startsWith("-")) {
// although not prefered, allow option value to be specified as --option=value
int ix = optionName.indexOf("=");
if (ix > 1) {
value = optionName.substring(ix + 1);
optionName = optionName.substring(0, ix);
}
}
String option = optionName;
View on GitHub (pinned to d5f144c24d)
Solutions
- Add the new command's option set to ALLOWED_OPTION_MAP in the static initializer block (around line 170).
- Ensure defineCommand() and the ALLOWED_OPTION_MAP.put() call are both present for any new command.
- Add an integration test that runs the command through BSimLaunchable.run() to catch the missing entry.
Example fix
// before: command registered but not in ALLOWED_OPTION_MAP
private static final String COMMAND_NEW_CMD = defineCommand("newcmd");
// ...
static {
ALLOWED_OPTION_MAP.put(COMMAND_CREATE_DATABASE, CREATE_DATABASE_OPTIONS);
// COMMAND_NEW_CMD missing!
}
// after
private static final Set<String> NEW_CMD_OPTIONS = Set.of(NAME_OPTION);
static {
ALLOWED_OPTION_MAP.put(COMMAND_NEW_CMD, NEW_CMD_OPTIONS); Defensive patterns
Strategy: validation
Validate before calling
if (!ALLOWED_OPTION_MAP.containsKey(command)) {
throw new IllegalStateException(
"Programming bug: command '" + command + "' is registered in COMMAND_SET " +
"but missing from ALLOWED_OPTION_MAP");
} Prevention
- When adding a new BSim command, always add it to both COMMAND_SET (via defineCommand) and ALLOWED_OPTION_MAP.
- Write an integration test that runs each command through BSimLaunchable.run() to catch missing map entries.
- Consider a unit test that iterates COMMAND_SET and asserts every entry exists in ALLOWED_OPTION_MAP.
When it happens
Trigger: A new BSim command is added to COMMAND_SET via defineCommand() but the developer omits the corresponding ALLOWED_OPTION_MAP.put(...) in the static block at lines 170-187. A user running that new command hits this before any work begins.
Common situations: Contributing a new BSim subcommand to Ghidra; the code compiles and passes unit tests that don't exercise the full CLI path, but the integration test or manual CLI run fails.
Related errors
- Unknown command: {}
- URL is not ghidra protocol: {}
- Invalid repository URL: {}
- Unable to infer ghidra URL from BSim file DB URL
- Unsupported option use: {}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/343dab46bbb56702.
Report an issue: GitHub.