{"record":{"id":"511ef39577bdc488","repo":"stanfordnlp/CoreNLP","slug":"unhandled-primitive-type-in-array-componenttype","errorCode":null,"errorMessage":"Unhandled primitive type in array: ${componentType}","messagePattern":"Unhandled primitive type in array: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/pipeline/JSONOutputter.java","lineNumber":520,"sourceCode":"            for (float elem : ((float[]) value)) {\n              lst.add(elem);\n            }\n            routeObject(indent, lst);\n          } else if (double.class.isAssignableFrom(componentType)) {\n            ArrayList<Double> lst = new ArrayList<>();\n            //noinspection Convert2streamapi\n            for (double elem : ((double[]) value)) {\n              lst.add(elem);\n            }\n            routeObject(indent, lst);\n          } else if (boolean.class.isAssignableFrom(componentType)) {\n            ArrayList<Boolean> lst = new ArrayList<>();\n            for (boolean elem : ((boolean[]) value)) {\n              lst.add(elem);\n            }\n            routeObject(indent, lst);\n          } else {\n            throw new IllegalStateException(\"Unhandled primitive type in array: \" + componentType);\n          }\n        } else {\n          routeObject(indent, Arrays.asList((Object[]) value));\n        }\n      } else if (value instanceof Integer) {\n        writer.write(Integer.toString((Integer) value));\n      } else if (value instanceof Short) {\n        writer.write(Short.toString((Short) value));\n      } else if (value instanceof Byte) {\n        writer.write(Byte.toString((Byte) value));\n      } else if (value instanceof Long) {\n        writer.write(Long.toString((Long) value));\n      } else if (value instanceof Character) {\n        writer.write(Character.toString((Character) value));\n      } else if (value instanceof Float) {\n        // Use the US Locale so that we can conform with json output format\n        // The decimal separator is always supposed to be . for example\n        Locale locale = Locale.US;","sourceCodeStart":502,"sourceCodeEnd":538,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/pipeline/JSONOutputter.java#L502-L538","documentation":"JSONOutputter's routeObject converts annotation values into JSON. It handles primitive arrays (int[], double[], boolean[], etc.) explicitly; when the array's component type is a primitive it does not handle (e.g. short[], char[], byte[], float[], long[]), an IllegalStateException is thrown because there is no conversion path.","triggerScenarios":"Passing a map/annotation value that is a primitive array of a type other than int/double/boolean — e.g. a long[], short[], char[], byte[], or float[] — into JSONOutputter's write/output path.","commonSituations":"Custom Annotator keys storing long[] or float[] statistics arrays; utility code that boxes most values but stores raw primitive arrays of less-common types; passing NLP feature vectors stored as byte[] or short[].","solutions":["Convert unsupported primitive arrays to List< boxedType > or the supported type (int[]/double[]/boolean[]) before passing to JSONOutputter","Box the array manually (e.g. ArrayUtils.toObject or a loop into ArrayList<Long>)","Change the annotator to store the value as a boxed array (Long[]/Float[]) or List so the Object[] branch handles it","If this is a CoreNLP bug, file/patch the missing primitive branch in routeObject"],"exampleFix":"// before\nannotations.put(CoreAnnotations.MyStats.class, new long[]{1L, 2L});\n// after\nannotations.put(CoreAnnotations.MyStats.class, new long[]{1L, 2L});\n// ...and before outputting:\nList<Long> boxed = Arrays.stream(longs).boxed().collect(Collectors.toList());","handlingStrategy":"type-guard","validationCode":"Object v = ann.get(key);\nClass<?> c = v.getClass();\nif (c.isArray() && c.getComponentType().isPrimitive()\n    && !(c == int[].class || c == double[].class || c == boolean[].class))\n  throw new IllegalArgumentException(\"Unsupported primitive array for JSON: \" + c);","typeGuard":"static boolean isJsonSafeArray(Object v) {\n  Class<?> c = v.getClass();\n  if (!c.isArray() || !c.getComponentType().isPrimitive()) return true;\n  return c == int[].class || c == double[].class || c == boolean[].class;\n}","tryCatchPattern":"try {\n  JSONOutputter.jsonPrint(writer, annotation);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Unhandled primitive type in array\")) {\n    // box the array or convert to List before re-serializing\n  } else throw e;\n}","preventionTips":["Store custom annotation values as boxed types or Lists, not raw primitive arrays","Restrict custom keys to int[]/double[]/boolean[] if arrays are needed","Test JSON output for every custom annotator key you add","Prefer List<Long>/List<Float> over long[]/float[] in annotation values"],"tags":["java","corenlp","json","serialization","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}