spring-projects/spring-ai · warning

VectorToolIndex does not support categoryFilter

Error message

VectorToolIndex does not support categoryFilter — '${categoryFilter}' will be ignored and results will not be narrowed by category.

What it means

VectorToolIndex performs semantic similarity search over a vector store and does not implement category-based filtering. If a ToolSearchRequest carries a categoryFilter, it logs this warning and ignores the filter, returning results narrowed only by similarity — never by category.

Solutions

  1. Remove categoryFilter from requests sent to VectorToolIndex or accept unfiltered semantic results.
  2. Switch to LuceneToolIndex or RegexToolIndex if category filtering is required.
  3. Embed category information into tool descriptions and/or include category terms in the query so semantic search effectively narrows results.
  4. Post-filter the returned ToolSearchResponse results by category in application code.

Example fix

// before: filter silently ignored
vectorToolIndex.search(ToolSearchRequest.builder().query("weather").categoryFilter("travel").build());
// after: include category signal in query or post-filter
var resp = vectorToolIndex.search(ToolSearchRequest.builder().query("weather").build());
var filtered = resp.tools().stream().filter(t -> "travel".equals(t.category())).toList();
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Calling search on a VectorToolIndex with ToolSearchRequest.builder().categoryFilter("...").build(); the filter value is logged and discarded.

Common situations: Reusing request-building code shared with Lucene/Regex indexes that support categoryFilter; switching the index backend from LuceneToolIndex to VectorToolIndex assuming feature parity; users adding categories to metadata expecting filtering.

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

Appendix: source

Thrown at spring-ai-tool-search-tool/src/main/java/org/springframework/ai/tool/toolsearch/index/vectorstore/VectorToolIndex.java:135

			documents.add(new Document(id, ref.summary(), Map.of(METADATA_SESSION_ID, sessionId, METADATA_ID, id,
					METADATA_TOOL_NAME, ref.toolName(), METADATA_TOOL_DESCRIPTION, ref.summary())));
		}

		this.vectorStore.add(documents);
		this.sessionToolIds.compute(sessionId, (k, existing) -> {
			List<String> list = existing != null ? new ArrayList<>(existing) : new ArrayList<>(ids.size());
			list.addAll(ids);
			return list;
		});
		if (logger.isInfoEnabled()) {
			logger.info("Indexed " + documents.size() + " tools for sessionId=" + sessionId);
		}
	}

	@Override
	public ToolSearchResponse search(ToolSearchRequest toolSearchRequest) {
		if (toolSearchRequest.categoryFilter() != null && logger.isWarnEnabled()) {
			logger.warn("VectorToolIndex does not support categoryFilter — '" + toolSearchRequest.categoryFilter()
					+ "' will be ignored and results will not be narrowed by category.");
		}
		int maxResults = toolSearchRequest.maxResults() != null ? toolSearchRequest.maxResults() : DEFAULT_MAX_RESULTS;

		List<Document> docs = this.doSearch(toolSearchRequest.query(), toolSearchRequest.sessionId(), maxResults,
				DEFAULT_SIMILARITY_THRESHOLD);

		List<ToolReference> toolReferences = docs.stream()
			.map(doc -> ToolReference.builder()
				.toolName((String) Objects.requireNonNull(doc.getMetadata().get(METADATA_TOOL_NAME)))
				.relevanceScore(Objects.requireNonNullElse(doc.getScore(), 0.0))
				.summary((String) Objects.requireNonNull(doc.getMetadata().get(METADATA_TOOL_DESCRIPTION)))
				.build())
			.toList();

		return ToolSearchResponse.builder()
			.toolReferences(toolReferences)
			.totalMatches(toolReferences.size())

View on GitHub (pinned to 98a7beda4f)