spring-projects/spring-ai · warning · UnsupportedOperationException

Documents are managed via data source, not direct delete.

Error message

Documents are managed via data source, not direct delete.

What it means

BedrockKnowledgeBaseVectorStore.delete(List<String> idList) is intentionally unsupported: document lifecycle is owned by the external data source and synchronized via ingestion jobs, so ID-based deletes at the vector-store level cannot be executed. Calls throw UnsupportedOperationException.

Source

Thrown at vector-stores/spring-ai-bedrock-knowledgebase-store/src/main/java/org/springframework/ai/vectorstore/bedrockknowledgebase/BedrockKnowledgeBaseVectorStore.java:108

	/**
	 * Creates a new builder for BedrockKnowledgeBaseVectorStore.
	 * @param client the Bedrock Agent Runtime client
	 * @param knowledgeBaseId the ID of the Knowledge Base to query
	 * @return a new builder instance
	 */
	public static Builder builder(final BedrockAgentRuntimeClient client, final String knowledgeBaseId) {
		return new Builder(client, knowledgeBaseId);
	}

	@Override
	public void add(final List<Document> documents) {
		throw new UnsupportedOperationException("Documents are ingested via data source sync, not direct add.");
	}

	@Override
	public void delete(final List<String> idList) {
		throw new UnsupportedOperationException("Documents are managed via data source, not direct delete.");
	}

	@Override
	public void delete(final Filter.Expression filterExpression) {
		throw new UnsupportedOperationException("Documents are managed via data source, not direct delete.");
	}

	@Override
	public List<Document> similaritySearch(final SearchRequest request) {
		Assert.notNull(request, "SearchRequest must not be null");
		Assert.hasText(request.getQuery(), "Query must not be empty");

		int topK = request.getTopK() > 0 ? request.getTopK() : this.defaultTopK;
		double threshold = request.getSimilarityThreshold() >= 0 ? request.getSimilarityThreshold()
				: this.defaultSimilarityThreshold;

		RetrievalFilter bedrockFilter = null;
		if (request.hasFilterExpression()) {

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Delete the source objects in the data source (e.g. S3 keys) and run a new ingestion/sync job so the knowledge base reflects removals
  2. Catch UnsupportedOperationException for delete-by-id on this store and implement data-source-driven cleanup instead
  3. Restructure pipelines so Bedrock KB stores are refreshed via full data-source sync rather than incremental deletes
  4. Add an explicit interface/capability check for delete support before invoking it on arbitrary VectorStore instances

Example fix

// before
store.delete(List.of(documentId)); // UnsupportedOperationException
// after
s3Client.deleteObject(b -> b.bucket(bucket).key(keyFor(documentId)));
bedrockAgentClient.startIngestionJob(b -> b.knowledgeBaseId(kbId).dataSourceId(dsId));
Defensive patterns

Strategy: try-catch

Validate before calling

if (store instanceof BedrockKnowledgeBaseVectorStore) { throw new IllegalStateException("Delete via data source + resync, not VectorStore.delete"); }

Type guard

boolean supportsDeleteById(VectorStore store) { return !(store instanceof BedrockKnowledgeBaseVectorStore); }

Try / catch

try { store.delete(idList); } catch (UnsupportedOperationException e) { deleteFromDataSourceAndResync(idList); }

Prevention

When it happens

Trigger: Calling store.delete(List.of("id1","id2")) on a BedrockKnowledgeBaseVectorStore, or generic cleanup/refresh code in a VectorStore abstraction that deletes by ID before re-upserting documents.

Common situations: Shared ingestion pipelines that do delete-then-add to keep stores in sync; migrating from ID-addressable stores (Redis, PgVector) where delete-by-id is standard; trying to remove individual documents without touching the source data.

Related errors


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