{"record":{"id":"11e4f35e85a68344","repo":"Tencent/APIJSON","slug":"cannot-convert-string-value-value-to-int","errorCode":null,"errorMessage":"Cannot convert String value '\" + value + \"' to int: \" + e.getMessage()","messagePattern":"Cannot convert String value '\" \\+ value \\+ \"' to int: \" \\+ e\\.getMessage\\(\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/JSON.java","lineNumber":385,"sourceCode":"\t * @param key The key\n\t * @return The int value\n\t * @throws IllegalArgumentException If value cannot be converted to int\n\t */\n\tpublic static Integer getInteger(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 Number) {\n\t\t\treturn ((Number) value).intValue();\n\t\t}\n\n\t\tif (value instanceof String) {\n\t\t\ttry {\n\t\t\t\treturn Integer.parseInt((String) value);\n\t\t\t} catch (NumberFormatException e) {\n\t\t\t\tthrow new IllegalArgumentException(\"Cannot convert String value '\" + value + \"' to int: \" + e.getMessage());\n\t\t\t}\n\t\t}\n\n\t\tthrow new IllegalArgumentException(\"Cannot convert value of type \" + value.getClass().getName() + \" to int\");\n\t}\n\n\t/**\n\t * Get an int value from a Map\n\t * @param map Source map\n\t * @param key The key\n\t * @return The int value\n\t * @throws IllegalArgumentException If value cannot be converted to int\n\t */\n\tpublic static int getIntValue(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 0;\n\t\t}","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/JSON.java#L367-L403","documentation":"Thrown by apijson.JSON.getInteger(Map, String) (APIJSONORM/src/main/java/apijson/JSON.java:385) when the value at the key is a String whose content cannot be parsed by Integer.parseInt. Only exact integer text is accepted — no leading/trailing whitespace, no decimal point, no hex, no thousands separators, no empty string.","triggerScenarios":"Value is \"1.0\" or \"12.5\" (Integer.parseInt rejects decimal points); value is \" 42 \" with surrounding whitespace; value is \"\" or \"null\"; value contains a unit or separator like \"1,000\" or \"12a\"; value overflows int range such as \"3000000000\".","commonSituations":"JSON producers serializing numeric fields as strings with formatting (prices \"12.99\", locale-formatted counts); frontends forwarding form inputs verbatim without trimming; Excel/CSV-derived payloads with padding or non-breaking spaces; IDs growing past Integer.MAX_VALUE; a literal \"null\" string when the source system nulls out fields as text.","solutions":["Trim and validate the string yourself before the call: value.toString().trim(), then check it matches ^[+-]?\\d+$ within int range.","If the number may legitimately be decimal (\"1.0\"), parse as double/BigDecimal first and narrow: (int) Double.parseDouble(str) or BigDecimal.valueOf(...).intValue().","Fix the producer to send a real JSON number instead of a formatted string — that takes the Number branch and never hits parseInt.","For values that can exceed int (large IDs, timestamps in ms), switch to JSON.getLong / getLongValue."],"exampleFix":"// before\nInteger count = JSON.getInteger(row, \"count\"); // throws on \"1,000\" or \"12.5\"\n\n// after\nObject raw = row.get(\"count\");\nInteger count = raw instanceof Number ? ((Number) raw).intValue()\n        : (raw instanceof String ? new java.math.BigDecimal(((String) raw).replace(\",\", \"\").trim()).intValue() : null);","handlingStrategy":"validation","validationCode":"Object v = row.get(\"count\");\nif (v instanceof String && !((String) v).trim().matches(\"[+-]?\\\\d+\")) {\n    throw new IllegalArgumentException(\"'count' is not integer text: \" + v);\n}","typeGuard":"static boolean isIntLike(Object v) {\n    if (v instanceof Number) return true;\n    if (v instanceof String) { String s = ((String) v).trim(); return s.matches(\"[+-]?\\\\d+\") && Math.abs(Long.parseLong(s)) <= Integer.MAX_VALUE; }\n    return false;\n}","tryCatchPattern":"try {\n    Integer count = JSON.getInteger(row, \"count\");\n} catch (IllegalArgumentException e) {\n    log.warn(\"Bad integer at 'count': {}\", e.getMessage());\n    // reject row, apply default, or re-parse via BigDecimal per your policy\n}","preventionTips":["Producers should emit JSON numbers, not formatted numeric strings.","Trim and regex-validate user-supplied numeric strings at the boundary.","Add contract tests asserting numeric fields deserialize as Number, not String."],"tags":["json","type-conversion","apijson","number-parsing"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}