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

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


The following commit(s) were added to refs/heads/main by this push:
     new 2fa665b8a08b CAMEL-26300: camel-milvus, camel-neo4j, camel-qdrant, 
camel-weaviate - the embeddings transformers name a missing embedding header, 
and neo4j:rag converts a text that is not a String (#29214)
2fa665b8a08b is described below

commit 2fa665b8a08b791b12474765bbf1b670c4d4641a
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Nov 5 13:02:55 2026 +0100

    CAMEL-26300: camel-milvus, camel-neo4j, camel-qdrant, camel-weaviate - the 
embeddings transformers name a missing embedding header, and neo4j:rag converts 
a text that is not a String (#29214)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../apache/camel/catalog/docs/neo4j-component.adoc |  1 +
 .../camel/catalog/transformers/neo4j-rag.json      |  2 +-
 .../MilvusEmbeddingsDataTypeTransformer.java       |  5 +++++
 .../MilvusEmbeddingsDataTypeTransformerTest.java   | 24 ++++++++++++++++++++--
 .../org/apache/camel/transformer/neo4j-rag.json    |  2 +-
 .../camel-neo4j/src/main/docs/neo4j-component.adoc |  1 +
 .../Neo4jEmbeddingDataTypeTransformer.java         |  5 +++++
 .../Neo4jReverseEmbeddingsDataTypeTransformer.java | 24 +++++++++++++++++++---
 .../Neo4jEmbeddingDataTypeTransformerTest.java     |  7 ++++++-
 ...4jReverseEmbeddingsDataTypeTransformerTest.java | 24 ++++++++++++++++++++++
 .../QdrantEmbeddingsDataTypeTransformer.java       |  5 +++++
 .../QdrantEmbeddingsDataTypeTransformerTest.java   |  7 +++++--
 .../WeaviateEmbeddingsDataTypeTransformer.java     |  5 +++++
 .../WeaviateEmbeddingsDataTypeTransformerTest.java | 18 +++++++++++-----
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    | 10 +++++++++
 15 files changed, 125 insertions(+), 15 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
index 7ba9d57c13e0..298fe2010758 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/neo4j-component.adoc
@@ -376,6 +376,7 @@ You can enhance the Camel LangChain4j chat RAG experience 
by integrating Neo4j s
 To achieve this, use the `neo4j:embeddings` DataType to generate embeddings 
from the prompt. These embeddings will then be utilized for the similarity 
search operation.
 
 Next, use the `neo4j:rag` DataType to convert the retrieved embeddings into a 
List<String> for RAG. This list can be directly used with the 
`LangChain4jRagAggregatorStrategy` from the LangChain4j chat component.
+Each element is the `text` property of a node: a value of another type, such 
as a number, is converted to a String, and a node without the property gives an 
empty String.
 
 NOTE: The retrieved embeddings must be ingested in Neo4j as LangChain4j 
embeddings.
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
index f565fc62d544..8072ca4ede62 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/transformers/neo4j-rag.json
@@ -16,7 +16,7 @@
         "list"
       ],
       "javaType": "java.util.List<java.util.Map<java.lang.String, 
java.lang.Object>>",
-      "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text keys 
are kept. A null body fails"
+      "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text 
values are kept as String: a value of another type, such as a number, is 
converted, and a row without text gives an empty String. A null body fails"
     },
     "transformerOut": {
       "carriers": [
diff --git 
a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
 
b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
index ea346133dfbd..55517fe71f95 100644
--- 
a/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
+++ 
b/components/camel-ai/camel-milvus/src/main/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformer.java
@@ -56,6 +56,11 @@ public class MilvusEmbeddingsDataTypeTransformer extends 
Transformer {
     @Override
     public void transform(Message message, DataType fromType, DataType toType) 
{
         Embedding embedding = 
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
 Embedding.class);
+        if (embedding == null) {
+            throw new IllegalArgumentException(
+                    "Missing embedding vector header '" + 
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+                                               + "'. Ensure the 
langchain4j-embeddings component is called before this transformer.");
+        }
         String textFieldName = 
message.getHeader(MilvusHeaders.TEXT_FIELD_NAME, () -> "text", String.class);
         String vectorFieldName = 
message.getHeader(MilvusHeaders.VECTOR_FIELD_NAME, () -> "vector", 
String.class);
         String collectionName = 
message.getHeader(MilvusHeaders.COLLECTION_NAME, () -> "embeddings", 
String.class);
diff --git 
a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
 
b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
index 945fee6f11d3..f074e1833bac 100644
--- 
a/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
+++ 
b/components/camel-ai/camel-milvus/src/test/java/org/apache/camel/component/milvus/transform/MilvusEmbeddingsDataTypeTransformerTest.java
@@ -67,10 +67,30 @@ class MilvusEmbeddingsDataTypeTransformerTest {
         }
     }
 
+    @Test
+    void aMessageWithoutTheEmbeddingFailsWithAClearMessage() throws Exception {
+        // CAMEL-26300: an IllegalArgumentException that names the missing 
header, as pgvector:embeddings gives, instead of
+        // a NullPointerException
+        try (DefaultCamelContext context = new DefaultCamelContext()) {
+            context.start();
+
+            for (MilvusAction action : new MilvusAction[] { 
MilvusAction.INSERT, MilvusAction.UPSERT }) {
+                assertThatThrownBy(() -> transform(context, 
TextSegment.from("hello"), action, null))
+                        .as(action.name())
+                        .isInstanceOf(IllegalArgumentException.class)
+                        
.hasMessageContaining("CamelLangChain4jEmbeddingsVector");
+            }
+        }
+    }
+
     private Object transform(DefaultCamelContext context, Object body, 
MilvusAction action) throws Exception {
+        return transform(context, body, action, new Embedding(new float[] { 
0.1f, 0.2f, 0.3f }));
+    }
+
+    private Object transform(DefaultCamelContext context, Object body, 
MilvusAction action, Embedding embedding)
+            throws Exception {
         Exchange exchange = new DefaultExchange(context);
-        
exchange.getMessage().setHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
-                new Embedding(new float[] { 0.1f, 0.2f, 0.3f }));
+        
exchange.getMessage().setHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
 embedding);
         exchange.getMessage().setHeader(MilvusHeaders.ACTION, action);
         exchange.getMessage().setBody(body);
         transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
diff --git 
a/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
 
b/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
index f565fc62d544..8072ca4ede62 100644
--- 
a/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
+++ 
b/components/camel-ai/camel-neo4j/src/generated/resources/META-INF/services/org/apache/camel/transformer/neo4j-rag.json
@@ -16,7 +16,7 @@
         "list"
       ],
       "javaType": "java.util.List<java.util.Map<java.lang.String, 
java.lang.Object>>",
-      "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text keys 
are kept. A null body fails"
+      "description": "The rows of a VECTOR_SIMILARITY_SEARCH, whose text 
values are kept as String: a value of another type, such as a number, is 
converted, and a row without text gives an empty String. A null body fails"
     },
     "transformerOut": {
       "carriers": [
diff --git a/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc 
b/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc
index 7ba9d57c13e0..298fe2010758 100644
--- a/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc
+++ b/components/camel-ai/camel-neo4j/src/main/docs/neo4j-component.adoc
@@ -376,6 +376,7 @@ You can enhance the Camel LangChain4j chat RAG experience 
by integrating Neo4j s
 To achieve this, use the `neo4j:embeddings` DataType to generate embeddings 
from the prompt. These embeddings will then be utilized for the similarity 
search operation.
 
 Next, use the `neo4j:rag` DataType to convert the retrieved embeddings into a 
List<String> for RAG. This list can be directly used with the 
`LangChain4jRagAggregatorStrategy` from the LangChain4j chat component.
+Each element is the `text` property of a node: a value of another type, such 
as a number, is converted to a String, and a node without the property gives an 
empty String.
 
 NOTE: The retrieved embeddings must be ingested in Neo4j as LangChain4j 
embeddings.
 
diff --git 
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
 
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
index 8c92dbd27627..2d04a792ee61 100644
--- 
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
+++ 
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformer.java
@@ -44,6 +44,11 @@ public class Neo4jEmbeddingDataTypeTransformer extends 
Transformer {
     public void transform(Message message, DataType fromType, DataType toType) 
{
         final Embedding embedding
                 = 
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
 Embedding.class);
+        if (embedding == null) {
+            throw new IllegalArgumentException(
+                    "Missing embedding vector header '" + 
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+                                               + "'. Ensure the 
langchain4j-embeddings component is called before this transformer.");
+        }
 
         final TextSegment text = message.getBody(TextSegment.class);
 
diff --git 
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
 
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
index 7f533fabd633..f54bf388b554 100644
--- 
a/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
+++ 
b/components/camel-ai/camel-neo4j/src/main/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformer.java
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.spi.BodyType;
 import org.apache.camel.spi.BodyType.Carrier;
@@ -36,20 +37,37 @@ import org.apache.camel.spi.Transformer;
                      description = "Prepares the similarity search LangChain4j 
embeddings to become a List of String for LangChain4j RAG")
 @BodyTypes(transformerIn = @BodyType(value = Carrier.LIST,
                                      javaType = 
"java.util.List<java.util.Map<java.lang.String, java.lang.Object>>",
-                                     description = "The rows of a 
VECTOR_SIMILARITY_SEARCH, whose text keys are kept. A"
-                                                   + " null body fails"),
+                                     description = "The rows of a 
VECTOR_SIMILARITY_SEARCH, whose text values are kept as"
+                                                   + " String: a value of 
another type, such as a number, is converted, and a"
+                                                   + " row without text gives 
an empty String. A null body fails"),
            transformerOut = @BodyType(value = Carrier.LIST, javaType = 
"java.util.List<java.lang.String>"))
 public class Neo4jReverseEmbeddingsDataTypeTransformer extends Transformer {
 
     @Override
     public void transform(Message message, DataType fromType, DataType toType) 
{
         final List<Map<String, Object>> embeddings = 
message.getBody(List.class);
+        final Exchange exchange = message.getExchange();
 
         List<String> result = embeddings.stream()
-                .map(embedding -> (String) embedding.getOrDefault("text", ""))
+                .map(embedding -> toText(exchange, embedding.get("text")))
                 .collect(Collectors.toList());
 
         message.setBody(result);
 
     }
+
+    /**
+     * The text of a row. The text of a node is a String, but a value of 
another type, such as a number, is converted
+     * instead of cast, and a row without text gives an empty String.
+     */
+    private static String toText(Exchange exchange, Object value) {
+        if (value == null) {
+            return "";
+        }
+        if (value instanceof String text) {
+            return text;
+        }
+        String text = 
exchange.getContext().getTypeConverter().convertTo(String.class, exchange, 
value);
+        return text != null ? text : "";
+    }
 }
diff --git 
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
 
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
index f55dbee8151f..440163614d8b 100644
--- 
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
+++ 
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jEmbeddingDataTypeTransformerTest.java
@@ -33,6 +33,7 @@ import static 
org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class Neo4jEmbeddingDataTypeTransformerTest {
 
@@ -61,7 +62,11 @@ class Neo4jEmbeddingDataTypeTransformerTest {
 
             // a null body fails, and so does a message without the embedding
             assertThrows(NullPointerException.class, () -> transform(context, 
null, true));
-            assertThrows(NullPointerException.class, () -> transform(context, 
TextSegment.from("hello"), false));
+            // CAMEL-26300: with an IllegalArgumentException that names the 
header, as pgvector:embeddings gives, instead
+            // of a NullPointerException
+            IllegalArgumentException noEmbedding
+                    = assertThrows(IllegalArgumentException.class, () -> 
transform(context, TextSegment.from("hello"), false));
+            
assertTrue(noEmbedding.getMessage().contains("CamelLangChain4jEmbeddingsVector"),
 noEmbedding.getMessage());
         }
     }
 
diff --git 
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
 
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
index 3ebbba00bdba..dabc020e428a 100644
--- 
a/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
+++ 
b/components/camel-ai/camel-neo4j/src/test/java/org/apache/camel/component/neo4j/transformer/Neo4jReverseEmbeddingsDataTypeTransformerTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.neo4j.transformer;
 
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -55,4 +57,26 @@ class Neo4jReverseEmbeddingsDataTypeTransformerTest {
         assertThrows(NullPointerException.class,
                 () -> transformer.transform(empty.getMessage(), DataType.ANY, 
DataType.ANY));
     }
+
+    @Test
+    void aTextThatIsNotAStringIsConverted() throws Exception {
+        // CAMEL-26300: a text value of another type, such as a number or 
bytes, is converted to a String instead of
+        // failing with a ClassCastException, and a null text gives an empty 
String, as a row without text does
+        Map<String, Object> nullText = new HashMap<>();
+        nullText.put("id", "4");
+        nullText.put("text", null);
+
+        try (DefaultCamelContext context = new DefaultCamelContext()) {
+            context.start();
+            Exchange exchange = new DefaultExchange(context);
+            exchange.getMessage().setBody(List.of(
+                    Map.of("id", "1", "text", 42L),
+                    Map.of("id", "2", "text", 0.5d),
+                    Map.of("id", "3", "text", 
"hello".getBytes(StandardCharsets.UTF_8)),
+                    nullText,
+                    Map.of("id", "5", "text", "hello")));
+            transformer.transform(exchange.getMessage(), DataType.ANY, 
DataType.ANY);
+            assertEquals(List.of("42", "0.5", "hello", "", "hello"), 
exchange.getMessage().getBody());
+        }
+    }
 }
diff --git 
a/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
 
b/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
index d95c43dabcbb..e0e3893e18cb 100644
--- 
a/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
+++ 
b/components/camel-ai/camel-qdrant/src/main/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformer.java
@@ -53,6 +53,11 @@ public class QdrantEmbeddingsDataTypeTransformer extends 
Transformer {
     @Override
     public void transform(Message message, DataType fromType, DataType toType) 
{
         Embedding embedding = 
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
 Embedding.class);
+        if (embedding == null) {
+            throw new IllegalArgumentException(
+                    "Missing embedding vector header '" + 
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+                                               + "'. Ensure the 
langchain4j-embeddings component is called before this transformer.");
+        }
         TextSegment text = message.getBody(TextSegment.class);
         Common.PointId id
                 = message.getHeader(QdrantHeaders.POINT_ID, () -> 
PointIdFactory.id(UUID.randomUUID()), Common.PointId.class);
diff --git 
a/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
 
b/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
index 9fb40a88e7b1..d71ab6e3d461 100644
--- 
a/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
+++ 
b/components/camel-ai/camel-qdrant/src/test/java/org/apache/camel/component/qdrant/transform/QdrantEmbeddingsDataTypeTransformerTest.java
@@ -101,11 +101,14 @@ class QdrantEmbeddingsDataTypeTransformerTest {
                 }
             }
 
-            // a message without the embedding fails
+            // CAMEL-26300: a message without the embedding fails with an 
IllegalArgumentException that names the header, as
+            // pgvector:embeddings gives, instead of a NullPointerException
             Exchange exchange = new DefaultExchange(context);
             exchange.getMessage().setBody(TextSegment.from("hello"));
             assertThatThrownBy(() -> new 
QdrantEmbeddingsDataTypeTransformer().transform(exchange.getMessage(),
-                    DataType.ANY, 
DataType.ANY)).isInstanceOf(NullPointerException.class);
+                    DataType.ANY, DataType.ANY))
+                    .isInstanceOf(IllegalArgumentException.class)
+                    .hasMessageContaining("CamelLangChain4jEmbeddingsVector");
         }
     }
 }
diff --git 
a/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
 
b/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
index 8444e610c849..6d83a9ed28cc 100644
--- 
a/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
+++ 
b/components/camel-ai/camel-weaviate/src/main/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformer.java
@@ -54,6 +54,11 @@ public class WeaviateEmbeddingsDataTypeTransformer extends 
Transformer {
     @Override
     public void transform(Message message, DataType fromType, DataType toType) 
{
         Embedding embedding = 
message.getHeader(CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR,
 Embedding.class);
+        if (embedding == null) {
+            throw new IllegalArgumentException(
+                    "Missing embedding vector header '" + 
CamelLangchain4jAttributes.CAMEL_LANGCHAIN4J_EMBEDDING_VECTOR
+                                               + "'. Ensure the 
langchain4j-embeddings component is called before this transformer.");
+        }
         String textFieldName = 
message.getHeader(WeaviateVectorDbHeaders.TEXT_FIELD_NAME, () -> "text", 
String.class);
         String collectionName = 
message.getHeader(WeaviateVectorDbHeaders.COLLECTION_NAME, () -> "embeddings", 
String.class);
         String keyName = message.getHeader(WeaviateVectorDbHeaders.KEY_NAME, 
() -> "id", String.class);
diff --git 
a/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
 
b/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
index 06d014acf254..83c70c7d7287 100644
--- 
a/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
+++ 
b/components/camel-ai/camel-weaviate/src/test/java/org/apache/camel/component/weaviate/transform/WeaviateEmbeddingsDataTypeTransformerTest.java
@@ -151,11 +151,19 @@ class WeaviateEmbeddingsDataTypeTransformerTest {
             noAction.setBody(TextSegment.from("hello"));
             assertThatThrownBy(() -> new 
WeaviateEmbeddingsDataTypeTransformer().transform(noAction, DataType.ANY,
                     DataType.ANY)).isInstanceOf(IllegalStateException.class);
-            Message noEmbedding = new DefaultExchange(context).getMessage();
-            noEmbedding.setHeader(WeaviateVectorDbHeaders.ACTION, 
WeaviateVectorDbAction.CREATE);
-            noEmbedding.setBody(TextSegment.from("hello"));
-            assertThatThrownBy(() -> new 
WeaviateEmbeddingsDataTypeTransformer().transform(noEmbedding, DataType.ANY,
-                    DataType.ANY)).isInstanceOf(NullPointerException.class);
+            // CAMEL-26300: without the embedding, an IllegalArgumentException 
that names the header, as
+            // pgvector:embeddings gives, instead of a NullPointerException
+            for (WeaviateVectorDbAction action : 
List.of(WeaviateVectorDbAction.CREATE, WeaviateVectorDbAction.UPDATE_BY_ID,
+                    WeaviateVectorDbAction.QUERY)) {
+                Message noEmbedding = new 
DefaultExchange(context).getMessage();
+                noEmbedding.setHeader(WeaviateVectorDbHeaders.ACTION, action);
+                noEmbedding.setBody(TextSegment.from("hello"));
+                assertThatThrownBy(() -> new 
WeaviateEmbeddingsDataTypeTransformer().transform(noEmbedding, DataType.ANY,
+                        DataType.ANY))
+                        .as(action.name())
+                        .isInstanceOf(IllegalArgumentException.class)
+                        
.hasMessageContaining("CamelLangChain4jEmbeddingsVector");
+            }
         }
     }
 }
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 9721138d273a..5b081f718d75 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -4145,6 +4145,16 @@ became `café` in the headers and the body map. A 
charset that the request or
 that sends ISO-8859-1 form data without declaring a charset now gets U+FFFD 
replacement characters instead of its
 text, and must declare its charset (for example 
`application/x-www-form-urlencoded; charset=ISO-8859-1`).
 
+=== camel-milvus, camel-neo4j, camel-qdrant, camel-weaviate - the embeddings 
transformers without the embedding header, and the text of neo4j:rag
+
+The `milvus:embeddings`, `neo4j:embeddings`, `qdrant:embeddings` and 
`weaviate:embeddings` data type transformers now
+fail with an `IllegalArgumentException` that names the 
`CamelLangChain4jEmbeddingsVector` header when the message does
+not have it, as `pgvector:embeddings` does. Before, they failed with a 
`NullPointerException`.
+
+The `neo4j:rag` data type transformer now converts a `text` value that is not 
a `String`, such as a number, to a
+`String`, and gives an empty String for a `null` text, as for a row without 
text. Before, a value of another type
+failed with a `ClassCastException`, and a `null` text gave a `null` element.
+
 === camel-undertow - rest-dsl and plain consumers on the same port are both 
served
 
 When rest-dsl consumers and plain `undertow:` consumers use the same port, 
both kinds are now served. Before, only the

Reply via email to