{"record":{"id":"14c0842ebde34973","repo":"skylot/jadx","slug":"unknown-value-val-for-option-name-expec","errorCode":null,"errorMessage":"Unknown value '${val}' for option '${name}', 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/BasePluginOptionsBuilder.java","lineNumber":122,"sourceCode":"\t\t\t\tthrow new RuntimeException(\"Parse failed for option: \" + option.name + \", value: \" + value, e);\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\toption.getSetter().accept(parsedValue);\n\t\t} catch (Exception e) {\n\t\t\tthrow new RuntimeException(\"Setter invoke failed for option: \" + option.name + \", value: \" + parsedValue, e);\n\t\t}\n\t}\n\n\tprivate static boolean parseBoolOption(String name, String val) {\n\t\tString valLower = val.trim().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 '\" + name + \"', expect: 'yes' or 'no'\");\n\t}\n\n\tprivate <T> OptionBuilder<T> addOption(OptionBuilder<T> optionData) {\n\t\tthis.options.add((OptionData<?>) optionData);\n\t\treturn optionData;\n\t}\n\n\tprotected static class OptionData<T> implements OptionDescription, OptionBuilder<T> {\n\t\tprivate final String name;\n\t\tprivate String desc;\n\t\tprivate List<T> values = Collections.emptyList();\n\t\tprivate OptionType type = OptionType.STRING;\n\t\tprivate Set<OptionFlag> flags = EnumSet.noneOf(OptionFlag.class);\n\t\tprivate Function<String, T> parser;\n\t\tprivate Function<T, String> formatter;\n\t\tprivate Consumer<T> setter;\n\t\tprivate T defaultValue;\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/api/plugins/options/impl/BasePluginOptionsBuilder.java#L104-L140","documentation":"Thrown by BasePluginOptionsBuilder.parseBoolOption when a boolean option value (after trim and lowercase) is not 'yes', 'true', 'no', or 'false'. This is the modern equivalent of error 40 used by boolOption registrations. Unlike the deprecated getBooleanOption, parseBoolOption does trim whitespace before checking, so only truly unrecognized tokens trigger it.","triggerScenarios":"A plugin registers a boolOption(name) and the user supplies a value outside {yes, true, no, false}. The value is trimmed and lowercased first, so '  YES ' works but '1', '0', 'on', 'off', 'enable', 'disable' do not. The parseBoolOption function is the parser for boolOption, so its IllegalArgumentException is then wrapped by parseOption (error 41).","commonSituations":"CLI users pass 1/0 or on/off for a boolean plugin option. A config migration from another tool that uses different boolean conventions. A typo such as 'tru' or 'flase'.","solutions":["Use 'yes' or 'no' (jadx convention) or 'true'/'false' for the boolean option value.","When building the options map in code, normalize with (b ? \"yes\" : \"no\").","Consult the plugin's option descriptions (getOptionsDescriptions) to confirm the option is boolean-typed before supplying a value."],"exampleFix":"// before\n// CLI: --plugin-option myplugin.verbose=1\n\n// after\n// CLI: --plugin-option myplugin.verbose=yes","handlingStrategy":"validation","validationCode":"String val = userOptionsMap.get(optionName);\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            \"Boolean option '\" + optionName + \"' must be yes/no/true/false, got: \" + val);\n    }\n}","typeGuard":"static boolean isValidBoolOptionValue(String val) {\n    if (val == null) return true;\n    String lower = val.trim().toLowerCase(Locale.ROOT);\n    return lower.equals(\"yes\") || lower.equals(\"true\")\n        || lower.equals(\"no\") || lower.equals(\"false\");\n}","tryCatchPattern":"try {\n    optionsBuilder.setOptions(userOptionsMap);\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof IllegalArgumentException\n            && cause.getMessage().contains(\"expect: 'yes' or 'no'\")) {\n        LOG.error(\"Invalid boolean value for plugin option: {}\", cause.getMessage());\n    } else {\n        throw e;\n    }\n}","preventionTips":["Use 'yes'/'no' as the convention for boolean plugin options in all documentation and config.","Trim whitespace from option values read from files before inserting into the options map.","Validate boolean values against the four accepted tokens before calling setOptions."],"tags":["options","boolean","plugin","validation"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}