spring-projects/spring-ai · error · RuntimeException

Unsupported value in NIN value list. Only supports String or

Error message

Unsupported value in NIN value list. Only supports String or Number

What it means

QdrantFilterExpressionConverter.buildNInCondition converts a Filter.Expression NIN operation into a Qdrant match-except condition. Every element of the list must be a String or a Number (Integer/Long/Double/Float); anything else, or an empty/invalid list, makes the condition unrepresentable so the converter throws this RuntimeException. It is thrown from inside expression conversion, so it surfaces when a filter is being translated for a search or delete call.

Source

Thrown at vector-stores/spring-ai-qdrant-store/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantFilterExpressionConverter.java:217

			if (firstValue instanceof String) {
				// If the first value is a string, then all values should be strings
				List<String> stringValues = new ArrayList<>();
				for (Object valueObj : valueList) {
					stringValues.add(valueObj.toString());
				}
				return io.qdrant.client.ConditionFactory.matchExceptKeywords(identifier, stringValues);
			}
			else if (firstValue instanceof Number) {
				// If the first value is a number, then all values should be numbers
				List<Long> longValues = new ArrayList<>();
				for (Object valueObj : valueList) {
					Long longValue = Long.parseLong(valueObj.toString());
					longValues.add(longValue);
				}
				return io.qdrant.client.ConditionFactory.matchExceptValues(identifier, longValues);
			}
			else {
				throw new RuntimeException("Unsupported value in NIN value list. Only supports String or Number");
			}
		}
		throw new RuntimeException(
				"Unsupported value type for NIN condition. Only supports non-empty List of String or Number");

	}

	protected String doKey(Key key) {
		var identifier = (hasOuterQuotes(key.key())) ? removeOuterQuotes(key.key()) : key.key();
		return identifier;
	}

	protected boolean hasOuterQuotes(String str) {
		str = str.trim();
		return (str.startsWith("\"") && str.endsWith("\"")) || (str.startsWith("'") && str.endsWith("'"));
	}

	protected String removeOuterQuotes(String in) {

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Ensure every element in the NIN value list is a String or a numeric type (Integer/Long/Double/Float)
  2. Convert unsupported element types before building the expression (e.g. boolean -> string)
  3. Use NIN only with a non-empty java.util.List value
  4. If you need mixed/complex matching, split into multiple expressions or pre-filter client-side

Example fix

// before
Filter.expr("color").nin(List.of("red", true));
// after
Filter.expr("color").nin(List.of("red", "blue")); // Strings or Numbers only
Defensive patterns

Strategy: validation

Validate before calling

if (!(v instanceof List<?> list) || list.isEmpty() || list.stream().anyMatch(e -> !(e instanceof String) && !(e instanceof Number))) throw new IllegalArgumentException("NIN requires non-empty List of String/Number");

Type guard

static boolean isNinSafe(Object v) { return v instanceof List<?> l && !l.isEmpty() && l.stream().allMatch(e -> e instanceof String || e instanceof Number); }

Try / catch

try { store.similaritySearch(req); } catch (RuntimeException e) { if (e.getMessage().contains("NIN")) { /* fix filter */ } else throw e; }

Prevention

When it happens

Trigger: Passing a NIN FilterExpression whose value list contains a Boolean, a nested List, a Map, or null; e.g. new Filter.Expression(NIN, meta("color"), new Value(List.of("red", true))).

Common situations: Building filter expressions programmatically from untyped metadata where a value of an unexpected type (boolean, nested array) slips into the NIN list; passing an empty list; passing a raw non-list value.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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