spring-projects/spring-ai · error · RuntimeException

Failed to insert:

Error message

Failed to insert:

What it means

MilvusVectorStore.doAdd inserts documents via the Milvus Java SDK client. The SDK always returns an R<MutationResult> wrapper; when status.getException() is non-null the call failed on the server or transport level, and the store rethrows it as RuntimeException("Failed to insert:", cause). The SDK's status message is not surfaced, so the cause must be inspected.

Solutions

  1. Inspect status exception in the stack trace (cause of this RuntimeException) for the real Milvus error code/message.
  2. Verify the embedding model's dimension matches the collection's VECTOR field dimension; recreate the collection if not (drop and re-initialize).
  3. Confirm the configured collection and partition names exist in Milvus (use Attu or listCollections).
  4. Check Milvus connectivity/credentials and that the collection is loaded into memory.
  5. Upgrade the milvus-sdk-java client version to match the server version.

Example fix

// before
EmbeddingModel model = new OpenAiEmbeddingModel(..., OpenAiEmbeddingOptions.ofModel("text-embedding-3-large")); // 3072 dims, collection is 1536
// after
// recreate collection with matching dimension or use a 1536-dim model
collectionName drop; vectorStore.afterPropertiesSet(); // re-init with matching embeddingModel
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check dimension against the Milvus collection schema before add:
// DescribeCollectionResponse desc = milvusClient.describeCollection(
//     DescribeCollectionParam.newBuilder().withCollectionName(name).build());
// assert desc.getData().getSchema() dimension == embeddingModel.dimensions()

Try / catch

try {
    vectorStore.add(documents);
} catch (RuntimeException e) {
    Throwable cause = e.getCause(); // Milvus SDK exception with real error code
    logger.error("Milvus insert failed: {}", cause == null ? e : cause.getMessage(), cause);
    // retry with backoff for transient errors; fix schema/dimension for others
}

Prevention

When it happens

Trigger: Calling vectorStore.add(List<Document>) when the Milvus insert RPC fails: collection doesn't exist, embedding dimension mismatch with the collection schema, collection not loaded, connection/auth problems, or partition name doesn't exist.

Common situations: Embedding model dimension changed (e.g. 1536 vs 768) but Milvus collection was created with the old dimension; partitionName configured but partition absent; Milvus server restarted or unreachable; wrong collection name config.

Related errors


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

Appendix: source

Thrown at vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusVectorStore.java:293

		if (!this.isAutoId) {
			fields.add(new InsertParam.Field(this.idFieldName, docIdArray));
		}
		fields.add(new InsertParam.Field(this.contentFieldName, contentArray));
		fields.add(new InsertParam.Field(this.metadataFieldName, metadataArray));
		fields.add(new InsertParam.Field(this.embeddingFieldName, embeddingArray));

		InsertParam.Builder insertParamBuilder = InsertParam.newBuilder()
			.withDatabaseName(this.databaseName)
			.withCollectionName(this.collectionName)
			.withFields(fields);
		if (StringUtils.hasText(this.partitionName)) {
			insertParamBuilder.withPartitionName(this.partitionName);
		}
		InsertParam insertParam = insertParamBuilder.build();

		R<MutationResult> status = this.milvusClient.insert(insertParam);
		if (status.getException() != null) {
			throw new RuntimeException("Failed to insert:", status.getException());
		}
	}

	@Override
	public void doDelete(List<String> idList) {
		Assert.notNull(idList, "Document id list must not be null");

		// Ids are user-supplied strings that get inlined into a Milvus filter
		// expression. Delegate escaping to the same Jackson-based JSON serialization
		// used by MilvusFilterExpressionConverter so quotes, backslashes and control
		// chars cannot break out of the string literal and inject filter syntax.
		String deleteExpression = String.format("%s in [%s]", this.idFieldName,
				idList.stream()
					.map(MilvusFilterExpressionConverter::toFilterExpressionLiteral)
					.collect(Collectors.joining(",")));

		DeleteParam.Builder deleteParamBuilder = DeleteParam.newBuilder()
			.withDatabaseName(this.databaseName)

View on GitHub (pinned to 98a7beda4f)