spring-projects/spring-ai · error · IllegalStateException

Failed to delete some documents

Error message

Failed to delete some documents

What it means

RedisVectorStore.doDelete() deletes documents by key in a pipeline and verifies each reply equals the expected deletion count (RESPONSE_DEL_OK). If any reply differs, it logs the offending response and throws an IllegalStateException meaning some documents were not deleted. A common cause is a key that no longer exists (DEL returns 0).

Source

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

				if (docs == null || docs.isEmpty()) {
					break;
				}

				try (Pipeline pipeline = this.jedisClient.pipelined()) {
					for (redis.clients.jedis.search.Document doc : docs) {
						String redisKey = doc.getId();
						String id = redisKey.startsWith(this.prefix) ? redisKey.substring(this.prefix.length())
								: redisKey;
						pipeline.jsonDel(key(id));
					}
					List<Object> responses = pipeline.syncAndReturnAll();
					Optional<Object> errResponse = responses.stream().filter(Predicate.not(RESPONSE_DEL_OK)).findAny();

					if (errResponse.isPresent()) {
						if (logger.isErrorEnabled()) {
							logger.error("Could not delete document: " + errResponse.get());
						}
						throw new IllegalStateException("Failed to delete some documents");
					}
				}

				deletedCount += docs.size();
			}

			if (logger.isDebugEnabled()) {
				logger.debug("Deleted " + deletedCount + " documents matching filter expression");
			}
		}
		catch (Exception e) {
			logger.error("Failed to delete documents by filter", e);
			throw new IllegalStateException("Failed to delete documents by filter", e);
		}
	}

	@Override
	public List<Document> doSimilaritySearch(SearchRequest request) {

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Verify the ids passed to delete() exist (e.g. check via getKey/FT.SEARCH) before deleting
  2. Ensure the store's key prefix matches the one used when documents were added
  3. Treat re-deletion of unknown ids defensively: filter ids to existing keys first
  4. Check for TTL/eviction settings in Redis that may have removed the keys
Defensive patterns

Strategy: validation

Validate before calling

// Only delete ids that exist
List<String> existing = ids.stream().filter(id -> jedisClient.exists(storePrefix + id)).toList();
store.delete(existing);

Try / catch

try { store.delete(ids); } catch (IllegalStateException e) { if (e.getMessage().equals("Failed to delete some documents")) { /* check prefix/TTL, skip missing ids */ } }

Prevention

When it happens

Trigger: Calling vectorStore.delete(List.of(id)) where at least one id has no corresponding key in Redis (already deleted, wrong prefix configured, or TTL expired), so DEL replies 0 instead of 1.

Common situations: Deleting the same document ids twice; store configured with a different key prefix than the one used at write time; expired keys (TTL set); id casing or whitespace mismatches.

Related errors


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