spring-projects/spring-ai · error · UnsupportedOperationException

Field type {0} not supported

Error message

Field type {0} not supported

What it means

doField renders a comparison for a metadata field according to its declared RediSearch field type (TAG, TEXT, NUMERIC). If the field's MetadataField.FieldType is not one of the handled types, the converter throws UnsupportedOperationException 'Field type {0} not supported'. Unknown or future field types cannot be translated into RediSearch query syntax.

Source

Thrown at vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisFilterExpressionConverter.java:139

				Numeric numeric = numeric(expression, value);
				context.append("[");
				context.append(numeric.lower());
				context.append(" ");
				context.append(numeric.upper());
				context.append("]");
				break;
			case TAG:
				context.append("{");
				context.append(tagStringValue(expression, value));
				context.append("}");
				break;
			case TEXT:
				context.append("(");
				context.append(textStringValue(expression, value));
				context.append(")");
				break;
			default:
				throw new UnsupportedOperationException(
						MessageFormat.format("Field type {0} not supported", field.fieldType()));
		}
	}

	private String tagStringValue(Expression expression, Value value) {
		String delimiter = tagValueDelimiter(expression);
		if (value.value() instanceof List<?> list) {
			return list.stream().map(String::valueOf).map(this::escapeTagValue).collect(Collectors.joining(delimiter));
		}
		return escapeTagValue(String.valueOf(value.value()));
	}

	private String textStringValue(Expression expression, Value value) {
		String delimiter = tagValueDelimiter(expression);
		if (value.value() instanceof List<?> list) {
			return list.stream()
				.map(String::valueOf)
				.map(RediSearchUtil::escapeQuery)

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Change the field to a supported type: MetadataField.tag, .text, or .numeric
  2. Check the spring-ai version's RedisFilterExpressionConverter for supported types and upgrade/downgrade accordingly
  3. Use the matching filter operand style for the field's actual type (numeric comparisons for NUMERIC, string equality for TEXT)
  4. Verify the MetadataField used at store-build time matches what the filter assumes

Example fix

// before
MetadataField.builder("ts").fieldType(CUSTOM).build();
// after
MetadataField.numeric("ts");
Defensive patterns

Strategy: validation

Validate before calling

Set<MetadataField.FieldType> supported = Set.of(TAG, TEXT, NUMERIC); if (!supported.contains(field.fieldType())) throw new UnsupportedOperationException("Field type not supported: " + field.fieldType());

Type guard

static boolean isSupportedFieldType(MetadataField f) { return EnumSet.of(FieldType.TAG, FieldType.TEXT, FieldType.NUMERIC).contains(f.fieldType()); }

Try / catch

try { vectorStore.similaritySearch(request); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("Field type")) { /* reconfigure field type */ } else throw e; }

Prevention

When it happens

Trigger: A filter expression on a metadata field whose configured FieldType falls into the default branch of the switch, e.g. a custom/unsupported field type added in a newer version or a wrongly typed MetadataField.

Common situations: Version drift where the converter doesn't handle a newly introduced field type; manually constructing metadata fields with an unexpected type.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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