{"record":{"id":"f80e4f80df9dbcc5","repo":"skylot/jadx","slug":"unknown-value-val-for-option-key-expect","errorCode":null,"errorMessage":"Unknown value '${val}' for option '${key}', expect: 'yes' or 'no'","messagePattern":"Unknown value '(.+?)' for option '(.+?)', expect: 'yes' or 'no'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/api/plugins/options/impl/BaseOptionsParser.java","lineNumber":37,"sourceCode":"\t\tthis.options = options;\n\t\tparseOptions();\n\t}\n\n\tpublic abstract void parseOptions();\n\n\tpublic boolean getBooleanOption(String key, boolean defValue) {\n\t\tString val = options.get(key);\n\t\tif (val == null) {\n\t\t\treturn defValue;\n\t\t}\n\t\tString valLower = val.toLowerCase(Locale.ROOT);\n\t\tif (valLower.equals(\"yes\") || valLower.equals(\"true\")) {\n\t\t\treturn true;\n\t\t}\n\t\tif (valLower.equals(\"no\") || valLower.equals(\"false\")) {\n\t\t\treturn false;\n\t\t}\n\t\tthrow new IllegalArgumentException(\"Unknown value '\" + val + \"' for option '\" + key + \"'\"\n\t\t\t\t+ \", expect: 'yes' or 'no'\");\n\t}\n\n\tpublic <T> T getOption(String key, Function<String, T> parse, T defValue) {\n\t\tString val = options.get(key);\n\t\tif (val == null) {\n\t\t\treturn defValue;\n\t\t}\n\t\treturn parse.apply(val);\n\t}\n}\n","sourceCodeStart":19,"sourceCodeEnd":49,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/api/plugins/options/impl/BaseOptionsParser.java#L19-L49","documentation":"Thrown by the deprecated BaseOptionsParser.getBooleanOption when a plugin option value is not one of the accepted boolean strings ('yes', 'true', 'no', 'false', case-insensitive). Jadx plugins use this legacy API to read boolean options from the options map; any other string (including '1', '0', 'on', 'off', or typos) is rejected at parse time. The value of the offending option key and its invalid value are included in the message to aid diagnosis.","triggerScenarios":"A plugin extending BaseOptionsParser calls getBooleanOption(key, defValue) and the options map contains a value outside the set {yes, true, no, false} (case-insensitive). This typically happens when a user passes --plugin-option <name>=enable or =1 from the CLI, or when a config file supplies 'on'/'off'. The check occurs only when options.get(key) returns non-null; a null (missing) key returns defValue without error.","commonSituations":"CLI users accustomed to 1/0 or on/off boolean syntax pass those to jadx plugin options. Integration code builds the options map programmatically using Integer.toString(booleanToInt(x)) or 0/1. A typo like 'ture' instead of 'true', or trailing whitespace from a properties file not trimmed by this parser (note: getBooleanOption does NOT trim, unlike parseBoolOption in the newer builder).","solutions":["Change the option value to 'yes' or 'no' (jadx's preferred boolean vocabulary) or 'true'/'false'.","If building the options map programmatically, normalize booleans with (b ? \"yes\" : \"no\") before insertion.","Trim whitespace from values read from properties/ENV before placing them in the map, since BaseOptionsParser.getBooleanOption does not trim.","Migrate the plugin to BasePluginOptionsBuilder, whose parseBoolOption does trim whitespace before checking."],"exampleFix":"// before\nMap<String,String> opts = new HashMap<>();\nopts.put(\"debug\", \"on\");\nboolean debug = parser.getBooleanOption(\"debug\", false);\n\n// after\nMap<String,String> opts = new HashMap<>();\nopts.put(\"debug\", \"yes\");\nboolean debug = parser.getBooleanOption(\"debug\", false);","handlingStrategy":"validation","validationCode":"// Validate the boolean option value before calling getBooleanOption\nString val = options.get(key);\nif (val != null) {\n    String lower = val.trim().toLowerCase(Locale.ROOT);\n    if (!lower.equals(\"yes\") && !lower.equals(\"true\") && !lower.equals(\"no\") && !lower.equals(\"false\")) {\n        throw new IllegalArgumentException(\n            \"Invalid boolean value for '\" + key + \"': \" + val + \". Use yes/no/true/false.\");\n    }\n}\nboolean result = parser.getBooleanOption(key, defValue);","typeGuard":"static boolean isValidJadxBoolean(String val) {\n    if (val == null) return true; // null defers to default\n    String lower = val.toLowerCase(Locale.ROOT);\n    return lower.equals(\"yes\") || lower.equals(\"true\")\n        || lower.equals(\"no\") || lower.equals(\"false\");\n}","tryCatchPattern":"try {\n    boolean result = parser.getBooleanOption(key, defValue);\n} catch (IllegalArgumentException e) {\n    LOG.error(\"Invalid boolean option '{}', using default {}\", key, defValue);\n    return defValue;\n}","preventionTips":["Always normalize boolean option values to 'yes' or 'no' before inserting into the options map.","Document accepted boolean values ('yes', 'true', 'no', 'false') in plugin help text.","Note that getBooleanOption does NOT trim whitespace — trim values from config files before passing."],"tags":["options","boolean","plugin","validation","deprecated"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}