alibaba/spring-ai-alibaba · error · IOException
Failed to serialize metadata record {}
Error message
Failed to serialize metadata record {} What it means
While normalizing a Java record used as a metadata value, SerializationHelper invokes Jackson property accessors/serializers and catches IllegalArgumentException. When record property access throws (e.g. a compact constructor or accessor invariant is violated, or a value fails Jackson coercion), it is rethrown as IOException naming the record class.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/serializer/plain_text/jackson/SerializationHelper.java:213
if (shouldInclude(provider, propertyInclusion, property, propertyValue)) {
boolean hasAssignedSerializer = propertyWriter.isUnwrapping()
|| !propertyWriter.getName().equals(property.getName())
|| propertyWriter.getTypeSerializer() != null
|| (propertyValue == null
? propertyWriter.hasNullSerializer()
: propertyWriter.hasSerializer());
if (hasAssignedSerializer) {
normalized.putAll(applyPropertyWriter(provider, propertyWriter, record));
}
else {
normalized.put(property.getName(),
normalizeMetadataValue(provider, propertyValue,
propertyInclusion.getContentInclusion()));
}
}
}
catch (IllegalArgumentException ex) {
throw new IOException("Failed to serialize metadata record " + record.getClass().getName(), ex);
}
}
for (BeanPropertyWriter propertyWriter : remainingWriters) {
normalized.putAll(applyPropertyWriter(provider, propertyWriter, record));
}
return normalized;
}
return value;
}
private static boolean requiresRecordNormalization(SerializerProvider provider, Record record,
List<BeanPropertyDefinition> properties) throws IOException {
for (BeanPropertyDefinition property : properties) {
AnnotatedMember accessor = property.getAccessor();
if (accessor == null) {
continue;
}
try {View on GitHub (pinned to f82da0b50f)
Solutions
- Inspect the nested IllegalArgumentException cause to find which record property fails and fix the value before storing it in metadata
- Ensure all record components are of Jackson-serializable types (register JavaTimeModule etc. for dates, optionals)
- Make record accessors side-effect-free validation — validate in the compact constructor instead of failing during access
- Replace the problematic metadata value with a plain POJO/Map if the type keeps failing normalization
Example fix
// before: accessor throws on bad state
public record Range(int lo, int hi) { public int lo() { if (lo > hi) throw new IllegalArgumentException(); return lo; } }
// after: validate once in the compact constructor
public record Range(int lo, int hi) { public Range { if (lo > hi) throw new IllegalArgumentException("lo>hi"); } } Defensive patterns
Strategy: try-catch
Validate before calling
try { for (var c : record.getClass().getRecordComponents()) c.getAccessor().invoke(value); } catch (Exception e) { /* exclude this value from metadata */ } Type guard
boolean isMetadataSafe(Object v) {
return v == null || v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof Map || isSafelySerializableRecord(v);
} Try / catch
try { metadata.put(key, recordValue); } catch (IOException e) { if (e.getMessage().startsWith("Failed to serialize metadata record")) { metadata.put(key, String.valueOf(recordValue)); } else throw e; } Prevention
- Keep record accessors free of throwing validation; validate in compact constructors
- Only store Jackson-serializable types in graph metadata
- Register all needed Jackson modules on the shared ObjectMapper
When it happens
Trigger: normalizeMetadataValue -> record property normalization: calling a record accessor or Jackson's serialization of a property raised IllegalArgumentException — e.g. accessor validates and rejects its stored state, or an incompatible nested container value.
Common situations: Records with validating compact constructors whose fields were deserialized/modified inconsistently; metadata values containing types Jackson cannot serialize with the configured ObjectMapper (unregistered modules, unsupported containers).
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Failed to inspect metadata record {}
- serialization Http body map failed
- 序列化 defaultParameters 失败
- 序列化 supportedParameters 失败
- Failed to apply serializer for metadata property {}
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/ca0cf2b4a383c056.
Report an issue: GitHub.