spring-projects/spring-ai · error · RuntimeException

Vectors must not be null

Error message

Vectors must not be null

What it means

EmbeddingMath.cosineSimilarity throws a RuntimeException 'Vectors must not be null' when either input float[] is null. Unlike the length check, this guard uses RuntimeException rather than IllegalArgumentException.

Solutions

  1. Null-check both vectors before calling cosineSimilarity.
  2. Ensure embeddings are generated (and non-null) for every document before similarity ranking.
  3. Prefer Objects.requireNonNull early in your pipeline to fail at the source.

Example fix

// before
double s = EmbeddingMath.cosineSimilarity(queryVec, docVec); // docVec may be null

// after
if (queryVec != null && docVec != null) {
    double s = EmbeddingMath.cosineSimilarity(queryVec, docVec);
}
Defensive patterns

Strategy: validation

Validate before calling

if (vectorX == null || vectorY == null) {
    throw new IllegalArgumentException("embeddings must be computed before similarity");
}
double s = EmbeddingMath.cosineSimilarity(vectorX, vectorY);

Type guard

static boolean hasEmbedding(float[] v) { return v != null && v.length > 0; }

Try / catch

try {
    return EmbeddingMath.cosineSimilarity(x, y);
} catch (RuntimeException e) {
    if ("Vectors must not be null".equals(e.getMessage())) { return 0.0; }
    throw e;
}

Prevention

When it happens

Trigger: Passing a null embedding to cosineSimilarity, typically when an embedding call failed or returned null upstream, or comparing against a document whose vector was never computed.

Common situations: EmbeddingModel returning null on failure; deserialized stores with missing vectors; optional lookups yielding null before similarity computation.

Related errors


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

Appendix: source

Thrown at spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java:272

	@Override
	public VectorStoreObservationContext.Builder createObservationContextBuilder(String operationName) {

		return VectorStoreObservationContext.builder(VectorStoreProvider.SIMPLE.value(), operationName)
			.dimensions(this.embeddingModel.dimensions())
			.collectionName("in-memory-map")
			.similarityMetric(VectorStoreSimilarityMetric.COSINE.value());
	}

	public static final class EmbeddingMath {

		private EmbeddingMath() {
			throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
		}

		public static double cosineSimilarity(float[] vectorX, float[] vectorY) {
			if (vectorX == null || vectorY == null) {
				throw new RuntimeException("Vectors must not be null");
			}
			if (vectorX.length != vectorY.length) {
				throw new IllegalArgumentException("Vectors lengths must be equal");
			}

			float dotProduct = dotProduct(vectorX, vectorY);
			float normX = norm(vectorX);
			float normY = norm(vectorY);

			if (normX == 0 || normY == 0) {
				throw new IllegalArgumentException("Vectors cannot have zero norm");
			}

			return dotProduct / (Math.sqrt(normX) * Math.sqrt(normY));
		}

		public static float dotProduct(float[] vectorX, float[] vectorY) {
			if (vectorX.length != vectorY.length) {

View on GitHub (pinned to 98a7beda4f)