{"record":{"id":"cc3af208fd374fdd","repo":"Tencent/APIJSON","slug":"cannot-convert-string-value-value-to-boo","errorCode":null,"errorMessage":"Cannot convert String value '\" + value + \"' to boolean","messagePattern":"Cannot convert String value '\" \\+ value \\+ \"' to boolean","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/JSON.java","lineNumber":612,"sourceCode":"\t * @return The boolean value\n\t * @throws IllegalArgumentException If value cannot be converted to boolean\n\t */\n\tpublic static Boolean getBoolean(Map<String, Object> map, String key) throws IllegalArgumentException {\n\t\tObject value = map == null || key == null ? null : map.get(key);\n\t\tif (value == null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (value instanceof Boolean) {\n\t\t\treturn (Boolean) value;\n\t\t}\n\n\t\tif (value instanceof String) {\n\t\t\tString str = ((String) value).toLowerCase();\n\t\t\tif (str.equals(\"true\") || str.equals(\"false\")) {\n\t\t\t\treturn Boolean.parseBoolean(str);\n\t\t\t}\n\t\t\tthrow new IllegalArgumentException(\"Cannot convert String value '\" + value + \"' to boolean\");\n\t\t}\n\n\t\tif (value instanceof Number) {\n\t\t\tint intValue = ((Number) value).intValue();\n\t\t\tif (intValue == 0 || intValue == 1) {\n\t\t\t\treturn intValue != 0;\n\t\t\t}\n\t\t\tthrow new IllegalArgumentException(\"Cannot convert Number value '\" + value + \"' to boolean. Only 0 and 1 are supported.\");\n\t\t}\n\n\t\tthrow new IllegalArgumentException(\"Cannot convert value of type \" + value.getClass().getName() + \" to boolean\");\n\t}\n\n\t/**\n\t * Get a boolean value from a Map\n\t * @param map Source map\n\t * @param key The key\n\t * @return The boolean value","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/JSON.java#L594-L630","documentation":"Thrown by apijson.JSON.getBoolean(Map, String) (APIJSONORM/src/main/java/apijson/JSON.java:612) when the value is a String whose lowercased form is neither \"true\" nor \"false\". The check is exact-match after toLowerCase() — no trimming is done, so padded strings like \" true\" fail, and no synonyms (yes/no, on/off, 1/0 as text) are accepted.","triggerScenarios":"Value is \" true\" or \"true\\n\" (whitespace), \"TRUE \" (trailing space), \"yes\", \"1\", \"Y\", \"on\", \"enabled\", or an empty string; frontend sending tri-state text like \"maybe\"; enum-ish flags sent as words.","commonSituations":"HTML form checkboxes posting \"on\"; configs using Y/N or yes/no; values read from properties/CSV with trailing whitespace or BOM; optional flags sent as \"\" instead of omitted; localizing flag words.","solutions":["Trim and normalize the string before the call: value.trim().toLowerCase(), and map synonyms (yes/on/1 → true, no/off/0 → false) yourself.","Fix the producer to send real JSON booleans (true/false literals) so the Boolean branch handles it.","For 0/1 sent as numbers, note the Number branch already accepts them — just stop stringifying.","Treat unrecognized/blank text as an absent flag (getBoolean returns null for null) instead of letting it throw."],"exampleFix":"// before\nBoolean enabled = JSON.getBoolean(settings, \"enabled\"); // throws on \"on\"\n\n// after\nObject raw = settings.get(\"enabled\");\nBoolean enabled;\nif (raw instanceof Boolean) { enabled = (Boolean) raw; }\nelse if (raw instanceof String) {\n    String s = ((String) raw).trim().toLowerCase();\n    enabled = s.isEmpty() ? null : (\"true|yes|on|1\".contains(s) ? Boolean.TRUE : Boolean.FALSE);\n} else { enabled = null; }","handlingStrategy":"validation","validationCode":"Object v = settings.get(\"enabled\");\nif (v instanceof String) {\n    String s = ((String) v).trim().toLowerCase();\n    if (!s.equals(\"true\") && !s.equals(\"false\")) {\n        throw new IllegalArgumentException(\"'enabled' must be true/false, got: '\" + v + \"'\");\n    }\n}","typeGuard":"static boolean isBooleanLike(Object v) {\n    if (v instanceof Boolean || v == null) return true;\n    if (v instanceof String) { String s = ((String) v).trim().toLowerCase(); return s.equals(\"true\") || s.equals(\"false\"); }\n    if (v instanceof Number) { int i = ((Number) v).intValue(); return i == 0 || i == 1; }\n    return false;\n}","tryCatchPattern":"try {\n    Boolean enabled = JSON.getBoolean(settings, \"enabled\");\n} catch (IllegalArgumentException e) {\n    log.warn(\"Bad boolean at 'enabled': {}\", e.getMessage());\n    // normalize yes/no/on/off yourself, or reject with 400\n}","preventionTips":["Send real JSON booleans (true/false literals) for flags.","Trim and lowercase boolean text before passing it in; map synonyms (yes/on/1, no/off/0) at your boundary.","No trimming is done internally — even one stray space fails the exact match."],"tags":["json","type-conversion","apijson","boolean-parsing"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}