spring-projects/spring-ai · error · IllegalArgumentException
Not allowed filter identifier name:
Error message
Not allowed filter identifier name:
What it means
RedisFilterExpressionConverter.doKey validates that every filter field name is one of the configured metadata fields before emitting the @field: RediSearch query token. RediSearch query syntax has no escaping mechanism for field names, so unknown identifiers are rejected with IllegalArgumentException 'Not allowed filter identifier name: <name>' to prevent query injection through crafted field names.
Source
Thrown at vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisFilterExpressionConverter.java:68
@Override
protected void doStartGroup(Group group, StringBuilder context) {
context.append("(");
}
@Override
protected void doEndGroup(Group group, StringBuilder context) {
context.append(")");
}
@Override
protected void doKey(Key key, StringBuilder context) {
var identifier = key.key();
// RediSearch field names are bare identifiers in the @field: query syntax
// and have no escaping mechanism. Validate against the configured metadata
// fields to prevent query injection through crafted field names.
if (!this.metadataFields.containsKey(identifier)) {
throw new IllegalArgumentException("Not allowed filter identifier name: " + identifier);
}
context.append("@").append(identifier).append(":");
}
@Override
protected void doExpression(Expression expression, StringBuilder context) {
switch (expression.type()) {
case NIN:
doExpression(negate(ExpressionType.IN, expression), context);
break;
case NE:
doExpression(negate(ExpressionType.EQ, expression), context);
break;
case AND:
doBinaryOperation(" ", expression, context);
break;
case OR:
doBinaryOperation(" | ", expression, context);View on GitHub (pinned to 98a7beda4f)
Solutions
- Register the field in RedisVectorStore.builder().metadataFields(MetadataField.tag("category"), ...)
- Correct the field-name typo in the filter expression to match a registered metadata field
- Keep a single shared constant list of metadata fields used by both document writing and filters
- Catch IllegalArgumentException from search if filters are user-supplied and sanitize them first
Example fix
// before
RedisVectorStore.builder(jedis, model).metadataFields(MetadataField.tag("type")).build();
// filter uses Filter.expr("category") -> error
// after
RedisVectorStore.builder(jedis, model).metadataFields(MetadataField.tag("type"), MetadataField.tag("category")).build(); Defensive patterns
Strategy: validation
Validate before calling
if (!registeredMetadataFields.containsKey(filterKey)) throw new IllegalArgumentException("Filter field not registered: " + filterKey); Type guard
static boolean isAllowedField(String key, Map<String,MetadataField> fields) { return key != null && fields.containsKey(key); } Try / catch
try { vectorStore.similaritySearch(request); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Not allowed filter identifier")) { /* reject/sanitize user filter */ } else throw e; } Prevention
- Whitelist user-supplied filter keys against registered metadata fields before searching
- Keep one shared constants class for metadata field names
- Add tests asserting every filter key used in the app is registered
When it happens
Trigger: Using a FilterExpression whose key is not registered in RedisVectorStore's MetadataField configuration, e.g. Filter.expr("category") when only tags/price metadata fields were declared via metadataFields(...).
Common situations: Adding a new metadata key to documents but forgetting to register it in the store builder; typos in field names; switching stores without updating the allowed-field list.
Related errors
- Field type {0} not supported
- Expression of type %s requires a left operand
- Expression of type %s requires a right operand
- Expected a Key operand but got:
- Expected a Value operand but got:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/bd70aa1588efff70.
Report an issue: GitHub.