{"record":{"id":"e86053bfc9ad5b5d","repo":"spring-projects/spring-ai","slug":"unsupported-value-type-e86053","errorCode":null,"errorMessage":"Unsupported value type: ","messagePattern":"Unsupported value type: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverter.java","lineNumber":196,"sourceCode":"\t\t\tcontext.append(String.format(singleValueFormat, d));\n\t\t}\n\t\telse if (value instanceof Float f) {\n\t\t\tcontext.append(String.format(singleValueFormat, f));\n\t\t}\n\t\telse if (value instanceof Boolean b) {\n\t\t\tcontext.append(String.format(\"valueBoolean:%s \", b));\n\t\t}\n\t\telse if (value instanceof String s) {\n\t\t\tcontext.append(\"valueText:\");\n\t\t\temitJsonValue(s, context);\n\t\t\tcontext.append(\" \");\n\t\t}\n\t\telse if (value instanceof Date date) {\n\t\t\tString dateString = DateFormatUtils.format(date, \"yyyy-MM-dd'T'HH:mm:ssZZZZZ\");\n\t\t\tcontext.append(String.format(\"valueDate:\\\"%s\\\" \", dateString));\n\t\t}\n\t\telse {\n\t\t\tthrow new RuntimeException(\"Unsupported value type: \" + value);\n\t\t}\n\t}\n\n\t@Override\n\tprotected void doGroup(Group group, StringBuilder context) {\n\t\t// Replaces the group: AND((foo == \"bar\" OR bar == \"foo\"), \"boza\" == \"koza\") into\n\t\t// AND(AND(id != -1, (foo == \"bar\" OR bar == \"foo\")), \"boza\" == \"koza\") into\n\t\tthis.convertOperand(new Expression(ExpressionType.AND,\n\t\t\t\tnew Expression(ExpressionType.NE, new Filter.Key(\"id\"), new Filter.Value(\"-1\")), group.content()),\n\t\t\t\tcontext);\n\t}\n\n}\n","sourceCodeStart":178,"sourceCodeEnd":210,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/vector-stores/spring-ai-weaviate-store/src/main/java/org/springframework/ai/vectorstore/weaviate/WeaviateFilterExpressionConverter.java#L178-L210","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar expr = new Filter.Expression(EQ, new Key(\"priority\"), new Value(Priority.HIGH)); // enum\n// after\nvar expr = new Filter.Expression(EQ, new Key(\"priority\"), new Value(Priority.HIGH.name())); // String","handlingStrategy":"type-guard","validationCode":"if (!(v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof Date)) throw new IllegalArgumentException(\"Unsupported Weaviate filter value type: \" + v.getClass());","typeGuard":"static boolean isWeaviateFilterValue(Object v) { return v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof Date; }","tryCatchPattern":"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; }","preventionTips":["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"],"tags":["vector-store","weaviate","filter-expression","value-serialization","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}