spring-projects/spring-ai · error · RuntimeException

Failed to serialize the Document metadata:

Error message

Failed to serialize the Document metadata: 

What it means

In toWeaviateObject(), the Document's metadata map is serialized to JSON with JsonMapper before being stored in Weaviate. If Jackson fails (JacksonException), the store throws a RuntimeException naming the document text. Non-serializable metadata values are the cause.

Source

Thrown at vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateVectorStore.java:250

			}
		}

		if (!CollectionUtils.isEmpty(errorMessages)) {
			throw new RuntimeException("Failed to add documents because: \n" + errorMessages);
		}
	}

	private WeaviateObject toWeaviateObject(Document document, List<Document> documents, List<float[]> embeddings) {

		// https://weaviate.io/developers/weaviate/config-refs/datatypes
		Map<String, Object> fields = new HashMap<>();
		fields.put(this.options.getContentFieldName(), document.getText());
		try {
			String metadataString = JsonMapper.shared().writeValueAsString(document.getMetadata());
			fields.put(METADATA_FIELD_NAME, metadataString);
		}
		catch (JacksonException e) {
			throw new RuntimeException("Failed to serialize the Document metadata: " + document.getText());
		}

		// Add the filterable metadata fields as top level fields, allowing filler
		// expressions on them.
		for (MetadataField mf : this.filterMetadataFields) {
			if (document.getMetadata().containsKey(mf.name())) {
				fields.put(this.options.getMetaFieldPrefix() + mf.name(), document.getMetadata().get(mf.name()));
			}
		}

		return WeaviateObject.builder()
			.className(this.options.getObjectClass())
			.id(document.getId())
			.vector(EmbeddingUtils.toFloatArray(embeddings.get(documents.indexOf(document))))
			.properties(fields)
			.build();
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Restrict metadata values to JSON-safe types (String, Number, Boolean, List of primitives).
  2. Convert dates/times to ISO-8601 strings before adding: metadata.put("date", localDate.toString()).
  3. Flatten or toJsonString() any complex objects stored in metadata.
  4. If needed, configure JsonMapper with modules (JavaTimeModule) — though the safest fix is sanitizing metadata at construction time.

Example fix

// before
metadata.put("createdAt", LocalDateTime.now());
// after
metadata.put("createdAt", LocalDateTime.now().toString()); // ISO-8601 string, Jackson-safe
Defensive patterns

Strategy: validation

Validate before calling

docs.forEach(d -> { try { JsonMapper.shared().writeValueAsString(d.getMetadata()); } catch (Exception e) { throw new IllegalStateException("Document metadata not serializable: " + d.getId(), e); } });

Type guard

boolean safeMetadata(Map<String,Object> m) { return m.values().stream().allMatch(v -> v instanceof String || v instanceof Number || v instanceof Boolean); }

Try / catch

try { vectorStore.add(docs); } catch (RuntimeException e) { if (e.getMessage().startsWith("Failed to serialize the Document metadata")) { sanitizeAndRetry(docs); } }

Prevention

When it happens

Trigger: Calling VectorStore.add(List<Document>) with a Document whose metadata map contains values Jackson cannot write — e.g. raw Object instances, LocalDateTime without JavaTimeModule, nested non-POJO types, or self-referencing structures.

Common situations: Putting LocalDateTime/Instant into metadata without registering the JavaTimeModule; embedding application domain objects in metadata instead of primitives/String/List; reading metadata from another store with incompatible types.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/f49f454221b66a5d. Report an issue: GitHub.