spring-projects/spring-ai · error · RuntimeException

Error serializing value to JSON.

Error message

Error serializing value to JSON.

What it means

emitJsonValue serializes a filter value to JSON with Jackson's ObjectMapper. If writeValueAsString fails (JacksonException — e.g. an unserializable type, self-referencing object, or broken custom serializer), it wraps it in RuntimeException("Error serializing value to JSON.").

Source

Thrown at spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/converter/AbstractFilterExpressionConverter.java:280

	 * <p>
	 * This method uses Jackson's ObjectMapper to properly serialize all value types:
	 * <ul>
	 * <li>Strings: properly quoted and escaped with double quotes, backslashes, and
	 * control characters handled</li>
	 * <li>Numbers: formatted without quotes (e.g., 42, 3.14)</li>
	 * <li>Booleans: formatted as JSON literals {@code true} or {@code false}</li>
	 * <li>null: formatted as JSON literal {@code null}</li>
	 * <li>Other types: handled according to Jackson's default serialization</li>
	 * </ul>
	 * @param value the value to format (can be any type)
	 * @param context the context to append the JSON representation to
	 */
	protected static void emitJsonValue(Object value, StringBuilder context) {
		try {
			context.append(OBJECT_MAPPER.writeValueAsString(value));
		}
		catch (JacksonException e) {
			throw new RuntimeException("Error serializing value to JSON.", e);
		}
	}

	/**
	 * Convert the given group into a string representation.
	 * @param group the group to convert
	 * @param context the context to append the string representation to
	 */
	protected void doGroup(Group group, StringBuilder context) {
		this.doStartGroup(group, context);
		this.convertOperand(group.content(), context);
		this.doEndGroup(group, context);
	}

	/**
	 * Convert the given group into a string representation.
	 * @param group the group to convert
	 * @param context the context to append the string representation to

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Use simple value types (String, Number, Boolean, Date, List) as filter values instead of arbitrary POJOs
  2. Ensure the object is Jackson-serializable (public getters or @JsonProperty; no self-references)
  3. Register a Jackson module/serializer if a custom type must be used
  4. Catch RuntimeException around the conversion and log the offending value's class

Example fix

// before
new Filter.Value(myUnserializableDomainObject)
// after
new Filter.Value(myDomainObject.getId())
Defensive patterns

Strategy: validation

Validate before calling

new ObjectMapper().writeValueAsString(value); // pre-test serializability of custom value types

Try / catch

try { converted = converter.convertExpression(expr); }
catch (RuntimeException e) { if (e.getCause() instanceof JacksonException j) { throw new IllegalArgumentException("Filter value not JSON-serializable", j); } throw e; }

Prevention

When it happens

Trigger: Using a filter value of a type Jackson cannot serialize — e.g. a POJO without accessible properties, a self-referential object, or a type with a broken custom serializer — when converting filter expressions via doValue -> emitJsonValue.

Common situations: Passing rich domain objects instead of primitives/String/Number/Boolean/Date as filter values; custom Jackson modules that fail at serialization time; unserializable collection elements inside IN values.

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/539706fb46b002f6. Report an issue: GitHub.