This is an automated email from the ASF dual-hosted git repository.

mattcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new d65582f901 Fixes #8750 : Embed text: skip whitespace-only text instead 
of failing the batch (#8831)
d65582f901 is described below

commit d65582f901756f6ffd7b321a1217e084f6f9dd9a
Author: Bart Maertens <[email protected]>
AuthorDate: Fri Oct 9 22:53:40 2026 +0200

    Fixes #8750 : Embed text: skip whitespace-only text instead of failing the 
batch (#8831)
---
 .../ROOT/pages/pipeline/transforms/embedtext.adoc  |   2 +-
 integration-tests/ai/0004-embed-blank-text.hpl     | 412 +++++++++++++++++++++
 integration-tests/ai/README.md                     |   1 +
 .../ai/main-0004-embed-blank-text.hwf              |  91 +++++
 .../hop/ai/transforms/embedtext/EmbedText.java     |  11 +-
 .../hop/ai/transforms/embedtext/EmbedTextTest.java |  31 ++
 6 files changed, 546 insertions(+), 2 deletions(-)

diff --git 
a/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/embedtext.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/embedtext.adoc
index 8beb2d237a..0f36d147b8 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/embedtext.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/embedtext.adoc
@@ -70,7 +70,7 @@ Vector is the better choice when the Vector value type plugin 
is installed. When
 |Transform name|Name of the transform, unique within the pipeline.
 |AI provider|The AI provider serving the embedding model.
 |Model|Optional. Overrides the provider's EMBEDDING model for this transform 
only. Accepts variables.
-|Input field|Field holding the text to embed. A row whose text is empty is 
passed on with empty output fields rather than being dropped, and keeps its 
place in the stream.
+|Input field|Field holding the text to embed. A row whose text is empty or 
only whitespace is passed on with empty output fields rather than being 
dropped, and keeps its place in the stream.
 |Output field|Field the embedding is written to.
 |Output format|`STRING` for a JSON array, `VECTOR` for a Vector field.
 |Batch size|Rows buffered before the provider is called. Accepts variables. 
Rows with empty text are buffered so they keep their place in the stream, but 
are not sent, so a batch can send fewer texts than its size.
diff --git a/integration-tests/ai/0004-embed-blank-text.hpl 
b/integration-tests/ai/0004-embed-blank-text.hpl
new file mode 100644
index 0000000000..faa5c9c899
--- /dev/null
+++ b/integration-tests/ai/0004-embed-blank-text.hpl
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+  <info>
+    <name>0004-embed-blank-text</name>
+    <name_sync_with_filename>Y</name_sync_with_filename>
+    <description>Embed text in one batch that mixes text with empty and 
whitespace-only values.
+      The blank values are made by a formula, because a Data Grid turns a 
value of only spaces
+      into null before Embed text would see it.
+      The rows with text get an embedding, the others pass through without 
one, and no row is
+      lost. Sending blank text used to stop the transform for the whole batch 
(#8750).</description>
+    <extended_description/>
+    <pipeline_version/>
+    <pipeline_type>Normal</pipeline_type>
+    <pipeline_status>0</pipeline_status>
+    <parameters>
+    </parameters>
+    <capture_transform_performance>N</capture_transform_performance>
+    
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+    
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+    <created_user>-</created_user>
+    <created_date>2026/10/09 12:00:00.000</created_date>
+    <modified_user>-</modified_user>
+    <modified_date>2026/10/09 12:00:00.000</modified_date>
+    <key_for_session_key/>
+    <is_key_private>N</is_key_private>
+  </info>
+  <notepads>
+  </notepads>
+  <order>
+    <hop> <from>chunks</from> <to>make blank text</to> <enabled>Y</enabled> 
</hop>
+    <hop> <from>make blank text</from> <to>Embed text</to> 
<enabled>Y</enabled> </hop>
+    <hop> <from>Embed text</from> <to>has text?</to> <enabled>Y</enabled> 
</hop>
+    <hop> <from>has text?</from> <to>embedded</to> <enabled>Y</enabled> </hop>
+    <hop> <from>has text?</from> <to>not embedded</to> <enabled>Y</enabled> 
</hop>
+    <hop> <from>embedded</from> <to>OUTPUT</to> <enabled>Y</enabled> </hop>
+    <hop> <from>embedded</from> <to>Abort</to> <enabled>Y</enabled> </hop>
+    <hop> <from>not embedded</from> <to>OUTPUT</to> <enabled>Y</enabled> </hop>
+    <hop> <from>not embedded</from> <to>Abort</to> <enabled>Y</enabled> </hop>
+    <hop> <from>OUTPUT</from> <to>count rows</to> <enabled>Y</enabled> </hop>
+    <hop> <from>count rows</from> <to>check row count</to> 
<enabled>Y</enabled> </hop>
+    <hop> <from>check row count</from> <to>Done</to> <enabled>Y</enabled> 
</hop>
+    <hop> <from>check row count</from> <to>Abort</to> <enabled>Y</enabled> 
</hop>
+  </order>
+  <transform>
+    <name>chunks</name>
+    <type>DataGrid</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <data>
+      <line>
+        <item>Apache Hop is a data orchestration platform.</item>
+        <item/>
+        <item>Y</item>
+      </line>
+      <line>
+        <item/>
+        <item>spaces</item>
+        <item>N</item>
+      </line>
+      <line>
+        <item/>
+        <item>tab-newline</item>
+        <item>N</item>
+      </line>
+      <line>
+        <item/>
+        <item/>
+        <item>N</item>
+      </line>
+      <line>
+        <item>Embeddings turn text into vectors for retrieval.</item>
+        <item/>
+        <item>Y</item>
+      </line>
+    </data>
+    <fields>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>text</name>
+        <type>String</type>
+      </field>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>blank</name>
+        <type>String</type>
+      </field>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>has_text</name>
+        <type>String</type>
+      </field>
+    </fields>
+    <attributes/>
+    <GUI>
+      <xloc>96</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>make blank text</name>
+    <type>Formula</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <formulas>
+      <formula>
+        <field_name>chunk_text</field_name>
+        <formula>IF([blank]="spaces",REPT(" 
",3),IF([blank]="tab-newline",CHAR(9)&amp;" 
"&amp;CHAR(10),[text]&amp;""))</formula>
+        <replace_field/>
+        <value_length>-1</value_length>
+        <value_precision>-1</value_precision>
+        <value_type>2</value_type>
+      </formula>
+    </formulas>
+    <attributes/>
+    <GUI>
+      <xloc>176</xloc>
+      <yloc>176</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>Embed text</name>
+    <type>EmbedText</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <ai_provider>ollama-embeddings</ai_provider>
+    <model_name/>
+    <input_field>chunk_text</input_field>
+    <output_field>embedding</output_field>
+    <output_format>STRING</output_format>
+    <batch_size>16</batch_size>
+    <include_model_metadata>Y</include_model_metadata>
+    <model_field>embedding_model</model_field>
+    <dimensions_field>embedding_dimensions</dimensions_field>
+    <attributes/>
+    <GUI>
+      <xloc>256</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>has text?</name>
+    <type>FilterRows</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <send_true_to>embedded</send_true_to>
+    <send_false_to>not embedded</send_false_to>
+    <compare>
+      <condition>
+        <negated>N</negated>
+        <leftvalue>has_text</leftvalue>
+        <function>=</function>
+        <rightvalue/>
+        <value>
+          <name>constant</name>
+          <type>String</type>
+          <text>Y</text>
+          <length>-1</length>
+          <precision>-1</precision>
+          <isnull>N</isnull>
+          <mask>####0;-####0</mask>
+        </value>
+      </condition>
+    </compare>
+    <attributes/>
+    <GUI>
+      <xloc>416</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>embedded</name>
+    <type>FilterRows</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <send_true_to>OUTPUT</send_true_to>
+    <send_false_to>Abort</send_false_to>
+    <compare>
+      <condition>
+        <negated>N</negated>
+        <leftvalue>embedding</leftvalue>
+        <function>IS NOT NULL</function>
+        <rightvalue/>
+        <value>
+          <name>constant</name>
+          <type>String</type>
+          <text></text>
+          <length>-1</length>
+          <precision>-1</precision>
+          <isnull>N</isnull>
+          <mask>####0;-####0</mask>
+        </value>
+      </condition>
+    </compare>
+    <attributes/>
+    <GUI>
+      <xloc>576</xloc>
+      <yloc>48</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>not embedded</name>
+    <type>FilterRows</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <send_true_to>OUTPUT</send_true_to>
+    <send_false_to>Abort</send_false_to>
+    <compare>
+      <condition>
+        <negated>N</negated>
+        <leftvalue>embedding</leftvalue>
+        <function>IS NULL</function>
+        <rightvalue/>
+        <value>
+          <name>constant</name>
+          <type>String</type>
+          <text></text>
+          <length>-1</length>
+          <precision>-1</precision>
+          <isnull>N</isnull>
+          <mask>####0;-####0</mask>
+        </value>
+      </condition>
+    </compare>
+    <attributes/>
+    <GUI>
+      <xloc>576</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>OUTPUT</name>
+    <type>Dummy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+    <GUI>
+      <xloc>736</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>count rows</name>
+    <type>MemoryGroupBy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <give_back_row>N</give_back_row>
+    <group>
+    </group>
+    <fields>
+      <field>
+        <aggregate>row_count</aggregate>
+        <subject>has_text</subject>
+        <type>COUNT_ALL</type>
+        <valuefield/>
+      </field>
+    </fields>
+    <attributes/>
+    <GUI>
+      <xloc>896</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>check row count</name>
+    <type>FilterRows</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <send_true_to>Done</send_true_to>
+    <send_false_to>Abort</send_false_to>
+    <compare>
+      <condition>
+        <negated>N</negated>
+        <leftvalue>row_count</leftvalue>
+        <function>=</function>
+        <rightvalue/>
+        <value>
+          <name>constant</name>
+          <type>Integer</type>
+          <text>5</text>
+          <length>-1</length>
+          <precision>-1</precision>
+          <isnull>N</isnull>
+          <mask>####0;-####0</mask>
+        </value>
+      </condition>
+    </compare>
+    <attributes/>
+    <GUI>
+      <xloc>1056</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>Done</name>
+    <type>Dummy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+    <GUI>
+      <xloc>1216</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>Abort</name>
+    <type>Abort</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <row_threshold>0</row_threshold>
+    <message>Embed text gave a row with text no embedding, gave blank text an 
embedding, or lost a row. The row logged above shows what came back.</message>
+    <always_log_rows>Y</always_log_rows>
+    <abort_option>ABORT_WITH_ERROR</abort_option>
+    <attributes/>
+    <GUI>
+      <xloc>736</xloc>
+      <yloc>256</yloc>
+    </GUI>
+  </transform>
+  <transform_error_handling>
+  </transform_error_handling>
+  <attributes/>
+</pipeline>
diff --git a/integration-tests/ai/README.md b/integration-tests/ai/README.md
index cf5c67f1ab..7f0e465ce9 100644
--- a/integration-tests/ai/README.md
+++ b/integration-tests/ai/README.md
@@ -42,3 +42,4 @@ standard suite. See `disabled.txt`.
 | Test | Covers |
 |---|---|
 | `0001-embed-text` | The Embed text transform against `nomic-embed-text`: the 
vector width, the model name on the row, and that an embedding comes back. The 
vector values themselves vary per call, so they are not compared. |
+| `0004-embed-blank-text` | Embed text with empty and whitespace-only values 
in the same batch as real text: those rows pass through without an embedding, 
the others get one, and no row is lost. |
diff --git a/integration-tests/ai/main-0004-embed-blank-text.hwf 
b/integration-tests/ai/main-0004-embed-blank-text.hwf
new file mode 100644
index 0000000000..e0be40dcad
--- /dev/null
+++ b/integration-tests/ai/main-0004-embed-blank-text.hwf
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+  <name>main-0004-embed-blank-text</name>
+  <name_sync_with_filename>Y</name_sync_with_filename>
+  <description>Embed text against a real Ollama embedding model, with empty 
and whitespace-only text in the batch.</description>
+  <extended_description/>
+  <workflow_version/>
+  <created_user>-</created_user>
+  <created_date>2026/10/09 12:00:00.000</created_date>
+  <modified_user>-</modified_user>
+  <modified_date>2026/10/09 12:00:00.000</modified_date>
+  <parameters>
+    </parameters>
+  <actions>
+    <action>
+      <name>Start</name>
+      <description/>
+      <type>SPECIAL</type>
+      <attributes/>
+      <DayOfMonth>1</DayOfMonth>
+      <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+      <hour>12</hour>
+      <intervalMinutes>60</intervalMinutes>
+      <intervalSeconds>0</intervalSeconds>
+      <minutes>0</minutes>
+      <repeat>N</repeat>
+      <schedulerType>0</schedulerType>
+      <weekDay>1</weekDay>
+      <parallel>N</parallel>
+      <xloc>64</xloc>
+      <yloc>64</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>Embed blank text</name>
+      <description/>
+      <type>PIPELINE</type>
+      <attributes/>
+      <add_date>N</add_date>
+      <add_time>N</add_time>
+      <clear_files>N</clear_files>
+      <clear_rows>N</clear_rows>
+      <create_parent_folder>N</create_parent_folder>
+      <exec_per_row>N</exec_per_row>
+      <filename>${PROJECT_HOME}/0004-embed-blank-text.hpl</filename>
+      <loglevel>Basic</loglevel>
+      <parameters>
+        <pass_all_parameters>Y</pass_all_parameters>
+      </parameters>
+      <params_from_previous>N</params_from_previous>
+      <run_configuration>local</run_configuration>
+      <set_append_logfile>N</set_append_logfile>
+      <set_logfile>N</set_logfile>
+      <wait_until_finished>Y</wait_until_finished>
+      <parallel>N</parallel>
+      <xloc>256</xloc>
+      <yloc>80</yloc>
+      <attributes_hac/>
+    </action>
+  </actions>
+  <hops>
+    <hop>
+      <from>Start</from>
+      <to>Embed blank text</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>Y</unconditional>
+    </hop>
+  </hops>
+  <notepads>
+  </notepads>
+  <attributes/>
+</workflow>
diff --git 
a/plugins/tech/ai/src/main/java/org/apache/hop/ai/transforms/embedtext/EmbedText.java
 
b/plugins/tech/ai/src/main/java/org/apache/hop/ai/transforms/embedtext/EmbedText.java
index 709116845c..ef7c3e1fc6 100644
--- 
a/plugins/tech/ai/src/main/java/org/apache/hop/ai/transforms/embedtext/EmbedText.java
+++ 
b/plugins/tech/ai/src/main/java/org/apache/hop/ai/transforms/embedtext/EmbedText.java
@@ -84,7 +84,7 @@ public class EmbedText extends BaseTransform<EmbedTextMeta, 
EmbedTextData> {
     String text = data.inputRowMeta.getString(row, data.inputFieldIndex);
     data.pendingRows.add(row);
     // Null marks a row that needs no embedding. It still queues, so the 
output keeps input order.
-    data.pendingTexts.add(Utils.isEmpty(text) ? null : text);
+    data.pendingTexts.add(hasNothingToEmbed(text) ? null : text);
     if (data.pendingRows.size() >= data.batchSize) {
       flushBatch();
     }
@@ -160,6 +160,15 @@ public class EmbedText extends 
BaseTransform<EmbedTextMeta, EmbedTextData> {
     }
   }
 
+  /**
+   * True for text that has no content to embed. langchain4j refuses a text 
segment that trims to
+   * nothing, which takes control characters as well as spaces, and would stop 
the transform before
+   * the provider is called. Unicode whitespace has nothing to embed either.
+   */
+  static boolean hasNothingToEmbed(String text) {
+    return text == null || text.trim().isEmpty() || text.isBlank();
+  }
+
   private void withEmbedding(Object[] output, float[] vector) {
     int index = data.inputRowMeta.size();
     output[index++] = data.emitVector ? vector : toJsonArray(vector);
diff --git 
a/plugins/tech/ai/src/test/java/org/apache/hop/ai/transforms/embedtext/EmbedTextTest.java
 
b/plugins/tech/ai/src/test/java/org/apache/hop/ai/transforms/embedtext/EmbedTextTest.java
index ba2200e5c1..146e09eadb 100644
--- 
a/plugins/tech/ai/src/test/java/org/apache/hop/ai/transforms/embedtext/EmbedTextTest.java
+++ 
b/plugins/tech/ai/src/test/java/org/apache/hop/ai/transforms/embedtext/EmbedTextTest.java
@@ -17,6 +17,7 @@
 package org.apache.hop.ai.transforms.embedtext;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -102,6 +103,30 @@ class EmbedTextTest {
     assertEquals(2, passed.size(), "rows with nothing to embed are not 
dropped");
   }
 
+  @Test
+  void treatsWhitespaceOnlyTextAsEmpty() throws Exception {
+    // langchain4j refuses a blank text segment, which would stop the 
transform outright.
+    run(Arrays.asList(new Object[] {"first"}, new Object[] {" \t\n "}, new 
Object[] {"third"}));
+
+    assertEquals(3, passed.size());
+    assertEquals("[1.0,2.0]", passed.get(0)[1]);
+    assertEquals(" \t\n ", passed.get(1)[0], "the blank text itself is passed 
on unchanged");
+    assertNull(passed.get(1)[1], "a row with blank text gets no embedding");
+    assertEquals("[1.0,2.0]", passed.get(2)[1]);
+  }
+
+  @Test
+  void findsNothingToEmbedInTextThatOnlyHoldsWhitespaceOrControlCharacters() {
+    assertTrue(EmbedText.hasNothingToEmbed(null));
+    assertTrue(EmbedText.hasNothingToEmbed(""));
+    assertTrue(EmbedText.hasNothingToEmbed(" \t\r\n"));
+    // langchain4j trims these away and then refuses the segment.
+    assertTrue(EmbedText.hasNothingToEmbed("\u0000\u0007"));
+    // Unicode spaces that trim keeps.
+    assertTrue(EmbedText.hasNothingToEmbed("\u2003\u3000"));
+    assertFalse(EmbedText.hasNothingToEmbed(" a "));
+  }
+
   @Test
   void divertsOnlyTheRowsThatWereActuallySent() throws Exception {
     // A row with no text is not in the request, so a provider failure is not 
its failure.
@@ -165,6 +190,12 @@ class EmbedTextTest {
                 throw new RuntimeException("provider is down");
               }
               List<TextSegment> segments = invocation.getArgument(0);
+              // Like the providers, reject blank input for the whole request.
+              for (TextSegment segment : segments) {
+                if (segment.text().isBlank()) {
+                  throw new RuntimeException("input must not be blank");
+                }
+              }
               List<Embedding> embeddings = new ArrayList<>();
               for (int i = 0; i < segments.size(); i++) {
                 embeddings.add(Embedding.from(new float[] {1.0f, 2.0f}));

Reply via email to