spring-projects/spring-ai · error · RuntimeException

Could not add document: {0}

Error message

Could not add document: {0}

What it means

RedisVectorStore.doAdd() writes documents through a Jedis pipeline and checks every response against the expected OK reply. If any single document write in the batch returned an error response, it logs the offending reply and throws a RuntimeException with that response embedded in the message. This means at least one document in the add batch failed at the Redis server side (e.g. JSON.SET rejected).

Source

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

				var fields = new HashMap<String, Object>();
				float[] embedding = embeddings.get(i);

				// Normalize embeddings for COSINE distance metric
				if (this.distanceMetric == DistanceMetric.COSINE) {
					embedding = normalize(embedding);
				}

				fields.put(this.embeddingFieldName, embedding);
				fields.put(this.contentFieldName, document.getText());
				fields.putAll(document.getMetadata());
				pipeline.jsonSetWithEscape(key(document.getId()), JSON_SET_PATH, fields);
			}
			List<Object> responses = pipeline.syncAndReturnAll();
			Optional<Object> errResponse = responses.stream().filter(Predicate.not(RESPONSE_OK)).findAny();
			if (errResponse.isPresent()) {
				String message = MessageFormat.format("Could not add document: {0}", errResponse.get());
				logger.error(message);
				throw new RuntimeException(message);
			}
		}
	}

	private String key(String id) {
		return this.prefix + id;
	}

	@Override
	public void doDelete(List<String> idList) {
		try (Pipeline pipeline = this.jedisClient.pipelined()) {
			for (String id : idList) {
				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()) {

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Check the embedded response in the message to identify the failing command and fix the server-side cause
  2. Verify Redis has RedisJSON and RediSearch modules loaded (redis-modules.json / Redis Stack)
  3. Inspect the documents in the failing batch for values that break JSON serialization
  4. Ensure the target Redis instance is writable and not a read-only replica
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check: ensure modules and writability
String modules = jedisClient.info("modules"); // expect search & ReJSON
if (modules == null || !modules.contains("search")) throw new IllegalStateException("Redis Stack modules missing");

Try / catch

try { store.add(docs); } catch (RuntimeException e) { if (e.getMessage().startsWith("Could not add document:")) { /* inspect failing reply, retry batch individually */ } }

Prevention

When it happens

Trigger: Adding a batch of documents where at least one pipeline response is not 'OK', e.g. RedisJSON module missing, malformed resulting JSON document, key type conflicts, or OOM/replica read-only errors on the server.

Common situations: Redis server without the RediSearch/RedisJSON modules loaded; document metadata containing values that cannot serialize to JSON; index/schema mismatch after upgrading Redis; writing to a read-only replica.

Related errors


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