{"record":{"id":"ef292660b3ea2a88","repo":"alibaba/spring-ai-alibaba","slug":"failed-to-apply-serializer-for-metadata-property","errorCode":null,"errorMessage":"Failed to apply serializer for metadata property {}","messagePattern":"Failed to apply serializer for metadata property (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/serializer/plain_text/jackson/SerializationHelper.java","lineNumber":424,"sourceCode":"\t\t\t\treturn writer;\n\t\t\t}\n\t\t\tif (writer.getName().equals(property.getName())) {\n\t\t\t\treturn writer;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate static Map<String, Object> applyPropertyWriter(SerializerProvider provider,\n\t\t\tBeanPropertyWriter writer, Record record) throws IOException {\n\t\tObjectCodec codec = provider.getGenerator().getCodec();\n\t\ttry (TokenBuffer buffer = new TokenBuffer(codec, false)) {\n\t\t\tbuffer.writeStartObject();\n\t\t\ttry {\n\t\t\t\twriter.serializeAsField(record, buffer, provider);\n\t\t\t}\n\t\t\tcatch (Exception ex) {\n\t\t\t\tthrow new IOException(\"Failed to apply serializer for metadata property \" + writer.getName(), ex);\n\t\t\t}\n\t\t\tbuffer.writeEndObject();\n\t\t\ttry (JsonParser parser = buffer.asParser(codec)) {\n\t\t\t\treturn codec.readValue(parser, new TypeReference<>() {\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static Object preserveMapType(SerializerProvider provider, Map<?, ?> original,\n\t\t\tMap<Object, Object> normalized, boolean changed) {\n\t\tif (!changed) {\n\t\t\treturn original;\n\t\t}\n\t\tMap<Object, Object> copy = instantiateContainer(provider, original.getClass(), Map.class);\n\t\tif (copy == null) {\n\t\t\treturn normalized;\n\t\t}","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/serializer/plain_text/jackson/SerializationHelper.java#L406-L442","documentation":"applyPropertyWriter serializes one metadata record property through a TokenBuffer so it can be re-read into a normalized plain Map. If BeanPropertyWriter.serializeAsField throws for that property (custom serializer failure, accessor exception, unserializable value), the failure is wrapped as IOException naming the property.","triggerScenarios":"normalizeMetadataValue -> applyPropertyWriter: writer.serializeAsField(record, buffer, provider) throws for a specific property — e.g. a custom JsonSerializer throwing, infinite recursion, or accessor exception; also codec.readValue can fail if the buffered JSON does not map to Map<String,Object>.","commonSituations":"Custom Jackson serializers registered on metadata value types that throw or emit non-object JSON; properties of types requiring modules not registered (java.time, Optional); cyclic object graphs in metadata.","solutions":["Look at the cause chain to find the failing property and its custom serializer; fix or remove the custom serializer for metadata values","Register required Jackson modules (JavaTimeModule, Jdk8Module) on the ObjectMapper used by SerializationHelper","Keep metadata values as Jackson-friendly POJOs/Maps/records without cycles","As a workaround, pre-convert the metadata value to a Map with objectMapper.convertValue before storing"],"exampleFix":"// before: metadata holds object with custom throwing serializer\nmetadata.put(\"span\", new Span(Instant.now()));\n// after: store a normalized Map\nmetadata.put(\"span\", objectMapper.convertValue(new Span(Instant.now()), new TypeReference<Map<String,Object>>() {}));","handlingStrategy":"try-catch","validationCode":"try { objectMapper.convertValue(value, new TypeReference<Map<String,Object>>() {}); return true; } catch (IllegalArgumentException e) { return false; }","typeGuard":"boolean isNormalizable(Object v) {\n    try (TokenBuffer buf = new TokenBuffer(objectMapper, false)) { objectMapper.writeValue(buf, v); return true; } catch (Exception e) { return false; }\n}","tryCatchPattern":"try { metadata.put(key, value); } catch (IOException e) { if (e.getMessage().startsWith(\"Failed to apply serializer for metadata property\")) { metadata.put(key, value.toString()); } else throw e; }","preventionTips":["Test custom serializers on all types you place in metadata","Avoid cyclic or deeply nested objects in metadata","Register java.time/Jdk8 modules and keep ObjectMapper configuration consistent across writer and reader"],"tags":["serialization","jackson","metadata"],"backgroundTag":"json-serialization-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}