{"record":{"id":"00a03c171e2c858b","repo":"stanfordnlp/CoreNLP","slug":"unknown-object-to-serialize-value","errorCode":null,"errorMessage":"Unknown object to serialize: ${value}","messagePattern":"Unknown object to serialize: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/pipeline/JSONOutputter.java","lineNumber":568,"sourceCode":"        writer.write(Boolean.toString((Boolean) value));\n      } else if (int.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Integer.valueOf((int) value));\n      } else if (short.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Short.valueOf((short) value));\n      } else if (byte.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Byte.valueOf((byte) value));\n      } else if (long.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Long.valueOf((long) value));\n      } else if (char.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Character.valueOf((char) value));\n      } else if (float.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Float.valueOf((float) value));\n      } else if (double.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Double.valueOf((double) value));\n      } else if (boolean.class.isAssignableFrom(value.getClass())) {\n        routeObject(indent, Boolean.valueOf((boolean) value));\n      } else {\n        throw new RuntimeException(\"Unknown object to serialize: \" + value);\n      }\n    }\n\n    public void object(int indent, Consumer<Writer> callback) {\n      writer.write(\"{\");\n      final Pointer<Boolean> firstCall = new Pointer<>(true);\n      callback.accept((key, value) -> {\n        if (key != null && value != null) {\n          // First call overhead\n          if (!firstCall.dereference().orElse(false)) {\n            writer.write(\",\");\n          }\n          firstCall.set(false);\n          // Write the key\n          newline();\n          indent(indent + 1);\n          writer.write(\"\\\"\");\n          writer.write(StringUtils.escapeJsonString(key));","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/pipeline/JSONOutputter.java#L550-L586","documentation":"routeObject is JSONOutputter's type-dispatch: it walks through known Java types (String, Number, Boolean, Iterable, Map, arrays, etc.) and serializes each. If the value's class matches none of the branches — even after primitive boxing — a RuntimeException 'Unknown object to serialize' is thrown.","triggerScenarios":"Placing an arbitrary object (custom class, URI, Date, CoreLabel, etc.) into an annotation value or map that JSONOutputter attempts to render; the object is not a String, Number, Boolean, Collection, Map, or array.","commonSituations":"Custom annotators storing rich Java objects under custom keys and then expecting JSONOutputter to dump the whole annotation; forgetting to convert objects like Date or custom feature structures to primitives/strings first.","solutions":["Convert the value to a JSON-friendly type (String, Number, Boolean, List, Map) before writing output","Implement a custom JSONOutputter/Outputter that knows how to serialize your object type","Remove or filter non-serializable annotation keys before calling JSONOutputter.write","Prefer Objects.toString(value) if a plain string representation is acceptable"],"exampleFix":"// before\nmap.put(\"timestamp\", new Date()); // RuntimeException\n// after\nmap.put(\"timestamp\", new Date().toInstant().toString());","handlingStrategy":"validation","validationCode":"for (Object v : values) {\n  if (!(v instanceof String || v instanceof Number || v instanceof Boolean\n      || v instanceof Iterable || v instanceof Map\n      || (v != null && v.getClass().isArray())))\n    throw new IllegalArgumentException(\"Not JSON-serializable: \" + v.getClass());\n}","typeGuard":"static boolean isJsonSerializable(Object v) {\n  return v == null || v instanceof String || v instanceof Number || v instanceof Boolean\n      || v instanceof Iterable || v instanceof Map || v.getClass().isArray();\n}","tryCatchPattern":"try {\n  JSONOutputter.jsonPrint(writer, ann);\n} catch (RuntimeException e) {\n  if (e.getMessage().startsWith(\"Unknown object to serialize\")) {\n    // strip/convert custom keys and retry\n  } else throw e;\n}","preventionTips":["Convert custom objects to Strings/primitives/Maps before annotation output","Filter out non-serializable custom annotation keys before JSON dumping","Round-trip test JSON output whenever adding new annotator keys","Use Objects.toString() for opaque objects if a string form suffices"],"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"}