alibaba/spring-ai-alibaba · error · IllegalStateException
Metadata must be an object
Error message
Metadata must be an object
What it means
deserializeMetadata expects the 'metadata' JSON field of a serialized state/graph to be a JSON object that maps to Map<String,Object>. If the field exists but is a scalar, array, or other non-object node, the deserializer aborts with IllegalStateException because metadata cannot be represented otherwise.
Solutions
- Open the serialized file and make the 'metadata' field a JSON object ({...}) or remove it entirely (null/missing yields an empty map)
- Re-export the state with the same library version that wrote it originally
- If migrating formats, transform old metadata representation into a key/value object before loading
- Validate checkpoint JSON with a schema check (metadata: object|null) before loading
Example fix
// before
"metadata": "user-uploads"
// after
"metadata": {"owner": "user-uploads"} Defensive patterns
Strategy: validation
Validate before calling
JsonNode meta = root.get("metadata");
if (meta != null && !meta.isNull() && !meta.isObject()) throw new IllegalArgumentException("metadata must be a JSON object"); Type guard
boolean isObjectNode(JsonNode n) { return n == null || n.isNull() || n.isObject(); } Try / catch
try { loaded = loader.load(file); } catch (IllegalStateException e) { if ("Metadata must be an object".equals(e.getMessage())) { /* repair or regenerate the checkpoint */ } else throw e; } Prevention
- Validate checkpoint JSON against a schema before loading
- Do not hand-edit serialized state files
- When migrating formats, transform metadata to a key/value object explicitly
When it happens
Trigger: Loading a checkpoint/serialized state whose 'metadata' field is present but is a JSON scalar, string, or array instead of an object — typically from hand-editing, cross-version formats, or corrupt files.
Common situations: Manually written checkpoint JSON; metadata written by another tool/version with a different shape; truncated or concatenated JSON files.
Related errors
- Failed to deserialize store item
- Failed to retrieve item from file system
- APP_COMPONENT_DETAIL_ERROR
- bytes cannot be empty
- bytes cannot be empty
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/b55afa518f130161.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/serializer/plain_text/jackson/SerializationHelper.java:74
import com.fasterxml.jackson.databind.util.TokenBuffer;
class SerializationHelper {
static final String METADATA_FIELD = "metadata";
static Map<String, Object> deserializeMetadata(ObjectMapper mapper, JsonNode parentNode)
throws JsonProcessingException {
if (parentNode == null) {
return Map.of();
}
var node = parentNode.findValue(METADATA_FIELD);
if (node == null || node.isNull() || node.isEmpty()) {
return Map.of();
}
if (!node.isObject()) {
throw new IllegalStateException("Metadata must be an object");
}
return mapper.treeToValue(node, new TypeReference<>() {
});
}
static void serializeMetadata(JsonGenerator gen, SerializerProvider provider, Map<String, Object> metadata)
throws IOException {
gen.writeObjectField(METADATA_FIELD, normalizeMetadataValue(provider, metadata));
}
private static Object normalizeMetadataValue(SerializerProvider provider, Object value) throws IOException {
return normalizeMetadataValue(provider, value, JsonInclude.Include.ALWAYS);
}
private static Object normalizeMetadataValue(SerializerProvider provider, Object value,
JsonInclude.Include contentInclusion) throws IOException {
if (value instanceof Map<?, ?> map) {
boolean preserveContainer = hasClassSerializationOverrides(provider, map.getClass());View on GitHub (pinned to f82da0b50f)