spring-projects/spring-ai · warning

Empty embedding vector returned for input at index + indexCo

Error message

Empty embedding vector returned for input at index + indexCounter.get() + . Skipping.

What it means

Warning logged inside BedrockTitanEmbeddingModel.call() when the Titan invoke response for a given input contains a null or zero-length embedding vector. The input at that index is skipped entirely — no Embedding is added to the result — so the returned EmbeddingResponse has fewer embeddings than the request had instructions, and index numbering shifts accordingly.

Source

Thrown at models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingModel.java:117

		for (String inputContent : request.getInstructions()) {
			var apiRequest = createTitanEmbeddingRequest(inputContent, request.getOptions());

			try {
				TitanEmbeddingResponse response = Observation
					.createNotStarted("bedrock.embedding", this.observationRegistry)
					.lowCardinalityKeyValue("model", "titan")
					.lowCardinalityKeyValue("input_type", this.inputType.name().toLowerCase(Locale.ROOT))
					.highCardinalityKeyValue("input_length", String.valueOf(inputContent.length()))
					.observe(() -> {
						TitanEmbeddingResponse r = this.embeddingApi.embedding(apiRequest);
						Assert.notNull(r, "Embedding API returned null response");
						return r;
					});

				if (response.embedding() == null || response.embedding().length == 0) {
					if (logger.isWarnEnabled()) {
						logger.warn("Empty embedding vector returned for input at index " + indexCounter.get()
								+ ". Skipping.");
					}
					continue;
				}

				embeddings.add(new Embedding(response.embedding(), indexCounter.getAndIncrement()));

				if (response.inputTextTokenCount() != null) {
					tokenUsage += response.inputTextTokenCount();
				}
			}
			catch (Exception ex) {
				if (logger.isErrorEnabled()) {
					logger.error("Titan API embedding failed for input at index " + indexCounter.get() + ": "
							+ summarizeInput(inputContent), ex);
				}
				throw ex; // Optional: Continue instead of throwing if you want partial
							// success

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Sanitize inputs before calling: filter out null/blank strings from the instruction list.
  2. Check that the returned embeddings count matches the input count and re-embed skipped inputs.
  3. Verify the Titan model ID and region are correct; an unsupported model/region can yield degenerate responses.
  4. Retry the failed input individually if the empty vector looks transient.

Example fix

// before
List<String> inputs = chunks; // may contain blank chunks
// after
List<String> inputs = chunks.stream().filter(c -> c != null && !c.isBlank()).toList();
Defensive patterns

Strategy: validation

Validate before calling

List<String> safe = inputs.stream().filter(t -> t != null && !t.isBlank()).toList();
if (safe.size() != inputs.size()) log.warn("Dropped {} blank inputs before Titan embedding", inputs.size() - safe.size());

Type guard

static boolean hasEmptyEmbedding(Embedding e) { return e == null || e.getOutput() == null || e.getOutput().length == 0; }

Try / catch

EmbeddingResponse resp = titanModel.call(req);
List<Embedding> valid = resp.getResults().stream().filter(e -> e.getOutput() != null && e.getOutput().length > 0).toList();
if (valid.size() < inputs.size()) { /* re-embed or fail loudly */ }

Prevention

When it happens

Trigger: Titan returns HTTP 200 but embedding()==null or embedding().length==0 for one of the per-input invocations — e.g. empty/whitespace-only input text, input that Titan silently rejected, or a malformed model response body.

Common situations: Ingesting documents where some chunks are empty strings after splitting; requests containing only whitespace or control characters; intermittent Bedrock issues producing empty bodies; vector-store upserts later failing because of mismatched embedding counts.

Understand the failure class

Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.

Related errors


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