spring-projects/spring-ai · error · RuntimeException

Unsupported value type for NIN condition. Only supports non-

Error message

Unsupported value type for NIN condition. Only supports non-empty List of String or Number

What it means

buildNInCondition requires the NIN operation's value to be a non-empty java.util.List whose elements are Strings or Numbers. If the operand is not a List at all (single value, null, or other collection type), the converter cannot build a Qdrant match-except condition and throws this RuntimeException after the per-element checks.

Source

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

				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) {
		return in.substring(1, in.length() - 1);
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Wrap the operand in java.util.List before using NIN: Filter.expr("tag").nin(List.of("red"))
  2. Use EQ/NE instead of NIN when matching a single value
  3. Ensure the list is non-empty and elements are String or Number
  4. Validate the expression value type before passing it to the vector store

Example fix

// before
new Filter.Expression(ExpressionType.NIN, meta("tag"), new Value("red"));
// after
new Filter.Expression(ExpressionType.NIN, meta("tag"), new Value(List.of("red")));
Defensive patterns

Strategy: validation

Validate before calling

if (!(value instanceof List<?> list) || list.isEmpty()) throw new IllegalArgumentException("NIN operand must be a non-empty List");

Type guard

static boolean isNinList(Object v) { return v instanceof List<?> l && !l.isEmpty(); }

Try / catch

try { store.delete(expr); } catch (RuntimeException e) { if (e.getMessage().startsWith("Unsupported value type for NIN")) { /* wrap scalar in List */ } else throw e; }

Prevention

When it happens

Trigger: Calling nin() with a single value instead of a list, e.g. Filter.expr("tag").nin("red"), or passing null/empty collection, or a value object that is not a List.

Common situations: Confusing EQ/NIN semantics and passing a scalar to NIN; building expressions dynamically where the value may be null; migrating from another store whose NIN accepted scalars.

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