{"record":{"id":"1c2840455f3230c1","repo":"apache/druid","slug":"unknown-type-s-for-field-s","errorCode":null,"errorMessage":"Unknown type[%s] for field[%s]","messagePattern":"Unknown type\\[(.+?)\\] for field\\[(.+?)\\]","errorType":"exception","errorClass":"org.apache.druid.java.util.common.parsers.ParseException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/data/input/Rows.java","lineNumber":166,"sourceCode":"\n        asNumber = v;\n      }\n      catch (Exception e) {\n        if (throwParseExceptions) {\n          throw new ParseException(\n              String.valueOf(inputValue),\n              e,\n              \"Unable to parse value[%s] for field[%s]\",\n              inputValue,\n              name\n          );\n        } else {\n          return null;\n        }\n      }\n    } else {\n      if (throwParseExceptions) {\n        throw new ParseException(\n            String.valueOf(inputValue),\n            \"Unknown type[%s] for field[%s]\",\n            inputValue.getClass(),\n            name\n        );\n      } else {\n        return null;\n      }\n    }\n\n    if (outputType == null || asNumber == null) {\n      return asNumber;\n    } else if (outputType == ValueType.LONG) {\n      return asNumber.longValue();\n    } else if (outputType == ValueType.FLOAT) {\n      return asNumber.floatValue();\n    } else if (outputType == ValueType.DOUBLE) {\n      return asNumber.doubleValue();","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/data/input/Rows.java#L148-L184","documentation":"objectToNumber handles null, Number, and String inputs; anything else (e.g. a Map, List, byte[], or complex object) is not convertible to a number, so with throwParseExceptions=true it throws a ParseException reporting the value's Java class and field name. This catches structural mismatches where a field holds a non-scalar value where a number was expected.","triggerScenarios":"Passing a non-scalar input (nested JSON object/array, byte[], Timestamp object) as inputValue to Rows.objectToNumber with throwParseExceptions=true; ingestion mappings where a nested/complex field is wired into a numeric metric.","commonSituations":"JSON ingestion where the metric column is actually a nested object; flattenSpec producing arrays where scalars were expected; timestamp objects routed into numeric aggregators instead of being converted first.","solutions":["Add a flattenSpec/transform so the field is extracted to a scalar string or number before numeric conversion.","Convert the value upstream (e.g. parse timestamps to millis longs) before passing to objectToNumber.","Set throwParseExceptions=false to skip unconvertible values (returns null).","Correct the column's type spec so non-numeric fields are not treated as metrics."],"exampleFix":"// before\nNumber n = Rows.objectToNumber(\"tags\", Collections.singletonList(\"a\"), true);\n// after\nNumber n = Rows.objectToNumber(\"tags_count\", ((List<?>) value).size(), true);","handlingStrategy":"type-guard","validationCode":"boolean isScalarNumericCandidate(Object v) {\n  return v == null || v instanceof Number || v instanceof String;\n}","typeGuard":"Number toNumberSafe(Object v) {\n  if (v instanceof Number) return (Number) v;\n  if (v instanceof String) return Rows.objectToNumber(\"f\", v, false);\n  return null; // maps, lists, byte[] are not numeric\n}","tryCatchPattern":"try {\n  return Rows.objectToNumber(field, value, true);\n} catch (ParseException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Unknown type\")) {\n    log.warn(\"Field %s holds a non-scalar value of class %s\", field, value.getClass());\n    return null;\n  }\n  throw e;\n}","preventionTips":["Verify with a flattenSpec that nested JSON fields are flattened to scalars before mapping to metrics.","Check the actual Java/JSON class of ingestion fields during parser development.","Never feed arrays, maps, or byte[] into numeric aggregation paths.","Add a transform to convert complex values (e.g. timestamps) to numbers first."],"tags":["java","parse-exception","type-mismatch","druid-rows"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}