{"record":{"id":"63c9722f014739cb","repo":"apache/druid","slug":"unhandled-type-s","errorCode":null,"errorMessage":"Unhandled type: %s","messagePattern":"Unhandled type: (.+?)","errorType":"exception","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/AutoTypeColumnIndexer.java","lineNumber":736,"sourceCode":"                typeSet.add(ColumnType.LONG_ARRAY);\n                sizeEstimate = valueDictionary.addLongArray(theArray);\n                return new StructuredDataProcessor.ProcessedValue<>(theArray, sizeEstimate);\n              case DOUBLE:\n                typeSet.add(ColumnType.DOUBLE_ARRAY);\n                sizeEstimate = valueDictionary.addDoubleArray(theArray);\n                return new StructuredDataProcessor.ProcessedValue<>(theArray, sizeEstimate);\n              case STRING:\n                // empty arrays and arrays with all nulls are detected as string arrays, but don't count them as part of\n                // the type set yet, we'll handle that later when serializing\n                if (theArray.length == 0 || Arrays.stream(theArray).allMatch(Objects::isNull)) {\n                  typeSet.addUntypedArray();\n                } else {\n                  typeSet.add(ColumnType.STRING_ARRAY);\n                }\n                sizeEstimate = valueDictionary.addStringArray(theArray);\n                return new StructuredDataProcessor.ProcessedValue<>(theArray, sizeEstimate);\n              default:\n                throw new IAE(\"Unhandled type: %s\", columnType);\n            }\n          }\n        case STRING:\n          typeSet.add(ColumnType.STRING);\n          final String asString = eval.asString();\n          sizeEstimate = valueDictionary.addStringValue(asString);\n          return new StructuredDataProcessor.ProcessedValue<>(asString, sizeEstimate);\n        default:\n          throw new IAE(\"Unhandled type: %s\", columnType);\n      }\n    }\n\n    public FieldTypeInfo.MutableTypeSet getTypes()\n    {\n      return typeSet;\n    }\n\n    public boolean isSingleType()","sourceCodeStart":718,"sourceCodeEnd":754,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/AutoTypeColumnIndexer.java#L718-L754","documentation":"Inside the auto-type column processor's per-value handling switch, the evaluated column type falls into a case that has no handler (only STRING, LONG, DOUBLE, and specific array cases are handled). This is an internal invariant break — an unexpected ColumnType reached the indexer — and is thrown as IllegalArgumentException 'Unhandled type: %s'.","triggerScenarios":"A ColumnType value produced during auto-column processing (from eval.type() or type switches inside processValue) that is not one of the explicitly enumerated cases reaches the default branch, e.g. a newly added ColumnType (like COMPLEX or a new array type) ingested into an auto column.","commonSituations":"Ingesting complex/COMPLEX-typed values (e.g. sketches, HLL) into a useSchemaDiscovery auto column; running a newer/older Druid version where ColumnType enum values introduced later reach older switch code; expression-produced values with exotic types.","solutions":["Do not ingest COMPLEX or other unhandled column types into auto-type columns; move such data to explicitly typed columns.","Pre-process expressions so values are normalized to STRING/LONG/DOUBLE or their array forms before the auto processor sees them.","If a new ColumnType in the Druid version is the cause, upgrade the ingestion code (patch the switch) or downgrade/pin to compatible versions.","Check the input format/expressions producing the value and restrict castTo types to supported primitives."],"exampleFix":"// before: feeding an expression yielding COMPLEX into auto column\n\"expression\": \"hyper_unique(x)\"\n// after: convert to a string representation\n\"expression\": \"to_string(hyper_unique(x))\"","handlingStrategy":"validation","validationCode":"String t = eval.type().toString();\nif (!(t.equals(\"STRING\") || t.equals(\"LONG\") || t.equals(\"DOUBLE\")\n    || t.contains(\"ARRAY\"))) {\n  throw new IllegalArgumentException(\"unsupported for auto column: \" + t);\n}","typeGuard":"boolean supportedForAutoColumn(ExprEval<?> eval) {\n  ColumnType t = eval.type();\n  return t.isPrimitive() || t.isArray();\n}","tryCatchPattern":"try {\n  return processor.processValue(vals, supplier);\n} catch (IAE e) {\n  log.error(e, \"unhandled column type in auto indexer: %s\", e.getMessage());\n  throw new ParseException(null, e, \"bad column type\");\n}","preventionTips":["Exclude COMPLEX columns from useSchemaDiscovery ingestion","Convert exotic expression outputs to strings before indexing","Keep Druid components on the same version to avoid new ColumnType values","Add a pre-ingestion dry run to surface unhandled types early"],"tags":["java","ingestion","nested-columns","invariant","column-type"],"backgroundTag":"internal-invariant-violation","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"}