{"record":{"id":"b220f63ccf5d2f7a","repo":"apache/druid","slug":"cannot-parse-string-to-double","errorCode":null,"errorMessage":"Cannot parse string to double","messagePattern":"Cannot parse string to double","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/Numbers.java","lineNumber":185,"sourceCode":"      throw new IAE(\"Unknown object type [%s]\", val.getClass().getName());\n    }\n  }\n\n  /**\n   * Like {@link #tryParseDouble}, but does not produce a primitive and will explode if unable to produce a Double\n   * similar to {@link Double#parseDouble}\n   */\n  @Nullable\n  public static Double parseDoubleObject(@Nullable String val)\n  {\n    if (val == null) {\n      return null;\n    }\n    Double d = Doubles.tryParse(val);\n    if (d != null) {\n      return d;\n    }\n    throw new NumberFormatException(\"Cannot parse string to double\");\n  }\n\n  /**\n   * Like {@link #tryParseLong} but does not produce a primitive and will explode if unable to produce a Long\n   * similar to {@link Long#parseLong}\n   */\n  @Nullable\n  public static Long parseLongObject(@Nullable String val)\n  {\n    if (val == null) {\n      return null;\n    }\n    Long lobj = Longs.tryParse(val);\n    if (lobj != null) {\n      return lobj;\n    }\n    // try as a double, for \"ddd.dd\" , Longs.tryParse(..) returns null\n    Double dobj = Doubles.tryParse(val);","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/Numbers.java#L167-L203","documentation":"Numbers.parseDoubleObject(String) parses a String to a boxed Double using Guava's Doubles.tryParse. If the string cannot be parsed as a double, it throws NumberFormatException \"Cannot parse string to double\". It is the strict (exploding) counterpart of tryParseDouble.","triggerScenarios":"Calling Numbers.parseDoubleObject(s) with a non-numeric or malformed string such as \"abc\", \"1,000\" (comma groupings), an empty string, or a string with currency symbols.","commonSituations":"Parsing CSV/config/JSON string fields that are expected numeric but contain blanks, locale-formatted numbers, or stray whitespace/units (e.g. \"10ms\").","solutions":["Validate/trim and normalize the string (strip units, commas, whitespace) before parsing.","Use the lenient Numbers.tryParseDouble(s, nullValue) or Doubles.tryParse(s) and handle null instead of throwing.","Catch NumberFormatException and treat the value as null/NaN.","Fix the data source so the field is genuinely numeric."],"exampleFix":"// before\nDouble d = Numbers.parseDoubleObject(str);\n// after\nDouble d = Doubles.tryParse(str == null ? null : str.trim());\nif (d == null) { d = 0.0; /* or skip row */ }","handlingStrategy":"try-catch","validationCode":"Double d = (str == null) ? null : Doubles.tryParse(str.trim());\nif (d == null) { throw new IllegalArgumentException(\"Not a double: \" + str); }","typeGuard":"boolean isDoubleString(String s) { return s != null && Doubles.tryParse(s.trim()) != null; }","tryCatchPattern":"Double d;\ntry { d = Numbers.parseDoubleObject(s); } catch (NumberFormatException e) { LOG.warn(\"Unparseable double: %s\", s); d = null; }","preventionTips":["Prefer lenient Doubles.tryParse/tryParseDouble when nulls are acceptable","Trim and normalize locale-specific formatting before parsing","Validate string fields are numeric at ingestion time"],"tags":["numbers","number-format","parse-failure"],"backgroundTag":"invalid-argument-format","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}