spring-projects/spring-ai · error · RuntimeException
Unsupported value type:
Error message
Unsupported value type:
What it means
doSingleValue serializes operand values into Weaviate's GraphQL where-filter literal syntax (valueString, valueInt, valueBoolean, valueDate, ...). When a value's type has no mapping (e.g. arbitrary objects, enums, nested collections), it throws a RuntimeException 'Unsupported value type: '. Weaviate filters only support string/number/boolean/date primitives.
Solutions
- Coerce the value to a supported primitive (String, Number, Boolean, java.util.Date) before building the Filter.Value.
- Flatten complex metadata (e.g. store nested objects as separate scalar fields) and filter on the flattened fields.
- Add explicit conversion (e.g. enum -> name(), LocalDate -> Date) at the point where filter expressions are constructed.
Example fix
// before
var expr = new Filter.Expression(EQ, new Key("priority"), new Value(Priority.HIGH)); // enum
// after
var expr = new Filter.Expression(EQ, new Key("priority"), new Value(Priority.HIGH.name())); // String Defensive patterns
Strategy: type-guard
Validate before calling
if (!(v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof Date)) throw new IllegalArgumentException("Unsupported Weaviate filter value type: " + v.getClass()); Type guard
static boolean isWeaviateFilterValue(Object v) { return v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof Date; } Try / catch
try { vectorStore.similaritySearch(req); } catch (RuntimeException e) { if (e.getMessage().startsWith("Unsupported value type:")) { /* coerce value to String/Number/Boolean/Date and retry */ } else throw e; } Prevention
- Store only scalar metadata values in documents
- Coerce enums to name() and temporal types to Date/String before filtering
- Flatten nested objects into separate scalar metadata fields at ingestion
When it happens
Trigger: Filtering on metadata whose value is an unsupported Java type, e.g. a Map, custom POJO, enum, or array passed as a Filter.Value in a similaritySearch expression.
Common situations: Documents stored with complex metadata (nested objects, lists of objects) and filters built directly on those values; passing raw user input objects into filter values without coercion; timezone-naive or exotic date types.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot compare values of incompatible types
- Cannot compare values of incompatible types
- Cannot compare values of types
- Cannot compare values of types
- Expected a List value for
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/e86053bfc9ad5b5d.
Report an issue: GitHub.
Appendix: source
Thrown at vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverter.java:196
context.append(String.format(singleValueFormat, d));
}
else if (value instanceof Float f) {
context.append(String.format(singleValueFormat, f));
}
else if (value instanceof Boolean b) {
context.append(String.format("valueBoolean:%s ", b));
}
else if (value instanceof String s) {
context.append("valueText:");
emitJsonValue(s, context);
context.append(" ");
}
else if (value instanceof Date date) {
String dateString = DateFormatUtils.format(date, "yyyy-MM-dd'T'HH:mm:ssZZZZZ");
context.append(String.format("valueDate:\"%s\" ", dateString));
}
else {
throw new RuntimeException("Unsupported value type: " + value);
}
}
@Override
protected void doGroup(Group group, StringBuilder context) {
// Replaces the group: AND((foo == "bar" OR bar == "foo"), "boza" == "koza") into
// AND(AND(id != -1, (foo == "bar" OR bar == "foo")), "boza" == "koza") into
this.convertOperand(new Expression(ExpressionType.AND,
new Expression(ExpressionType.NE, new Filter.Key("id"), new Filter.Value("-1")), group.content()),
context);
}
}
View on GitHub (pinned to 98a7beda4f)