{"record":{"id":"5c83a4b1cb9c882c","repo":"spring-projects/spring-ai","slug":"vectors-cannot-have-zero-norm","errorCode":null,"errorMessage":"Vectors cannot have zero norm","messagePattern":"Vectors cannot have zero norm","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java","lineNumber":283,"sourceCode":"\n\t\tprivate EmbeddingMath() {\n\t\t\tthrow new UnsupportedOperationException(\"This is a utility class and cannot be instantiated\");\n\t\t}\n\n\t\tpublic static double cosineSimilarity(float[] vectorX, float[] vectorY) {\n\t\t\tif (vectorX == null || vectorY == null) {\n\t\t\t\tthrow new RuntimeException(\"Vectors must not be null\");\n\t\t\t}\n\t\t\tif (vectorX.length != vectorY.length) {\n\t\t\t\tthrow new IllegalArgumentException(\"Vectors lengths must be equal\");\n\t\t\t}\n\n\t\t\tfloat dotProduct = dotProduct(vectorX, vectorY);\n\t\t\tfloat normX = norm(vectorX);\n\t\t\tfloat normY = norm(vectorY);\n\n\t\t\tif (normX == 0 || normY == 0) {\n\t\t\t\tthrow new IllegalArgumentException(\"Vectors cannot have zero norm\");\n\t\t\t}\n\n\t\t\treturn dotProduct / (Math.sqrt(normX) * Math.sqrt(normY));\n\t\t}\n\n\t\tpublic static float dotProduct(float[] vectorX, float[] vectorY) {\n\t\t\tif (vectorX.length != vectorY.length) {\n\t\t\t\tthrow new IllegalArgumentException(\"Vectors lengths must be equal\");\n\t\t\t}\n\n\t\t\tfloat result = 0;\n\t\t\tfor (int i = 0; i < vectorX.length; ++i) {\n\t\t\t\tresult += vectorX[i] * vectorY[i];\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java#L265-L301","documentation":"EmbeddingMath.cosineSimilarity throws IllegalArgumentException 'Vectors cannot have zero norm' when either vector has zero Euclidean norm (all components zero), because cosine similarity would divide by zero. The norms here are sums of squares; a value of 0 means the vector is the zero vector.","triggerScenarios":"Comparing a zero-filled vector, e.g. an embedding initialized but never populated, an all-zeros placeholder, or an embedding model that returned an all-zero response.","commonSituations":"Uninitialized float arrays used as placeholders; embeddings from failed/edge-case model calls; hand-rolled test vectors of zeros.","solutions":["Check that embeddings are actually computed (non-zero) before similarity ranking.","Validate at ingestion: reject or re-embed documents whose vector norm is 0.","Fix the embedding pipeline so null/failed embeds never store all-zero vectors."],"exampleFix":"// before\ndouble s = EmbeddingMath.cosineSimilarity(queryVec, docVec); // docVec may be all zeros\n\n// after\nprivate boolean isZeroVector(float[] v) {\n    for (float x : v) { if (x != 0f) return false; }\n    return true;\n}\nif (!isZeroVector(docVec)) {\n    double s = EmbeddingMath.cosineSimilarity(queryVec, docVec);\n}","handlingStrategy":"validation","validationCode":"static boolean hasNonZeroNorm(float[] v) {\n    if (v == null) return false;\n    float sum = 0;\n    for (float x : v) { sum += x * x; }\n    return sum > 0f;\n}\nif (hasNonZeroNorm(vectorX) && hasNonZeroNorm(vectorY)) {\n    double s = EmbeddingMath.cosineSimilarity(vectorX, vectorY);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return EmbeddingMath.cosineSimilarity(x, y);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"zero norm\")) { return 0.0; }\n    throw e;\n}","preventionTips":["Never use all-zero arrays as placeholder embeddings.","Validate embedding outputs are non-trivial before storing."],"tags":["vector-math","zero-norm","division-by-zero"],"backgroundTag":"invalid-argument-value","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}