This is an automated email from the ASF dual-hosted git repository.
oscerd 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 bb3dc7ae17ec CAMEL-24614: camel-langchain4j-agent - clear error when
no agent can be resolved (validated at process time) (#26077)
bb3dc7ae17ec is described below
commit bb3dc7ae17ec0692c281cf9a8565bd03fc13c686
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Sep 4 11:10:35 2026 +0200
CAMEL-24614: camel-langchain4j-agent - clear error when no agent can be
resolved (validated at process time) (#26077)
* CAMEL-24614: camel-langchain4j-agent - fail fast when no agent can be
resolved
When an endpoint has no agent, agentConfiguration or agentFactory and no
registry
bean matches its agentId, lookupByNameAndType returns null and the producer
later
threw an opaque NullPointerException in process() at agent.chat(). Validate
in
doStart that an agent (or agentFactory) is available and throw a clear
IllegalArgumentException naming the endpoint and how to configure it.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Ka4dAcJMpxahMfk3kmG5Ls
Signed-off-by: Andrea Cosentino <[email protected]>
* CAMEL-24614: camel-langchain4j-agent - validate the agent at process time
to support late endpoint configuration
The producer resolved the agent once at doStart() and failed fast there when
nothing resolved. That broke the supported pattern of configuring an agent
on
the endpoint after the route has started (e.g. tests and dynamic wiring set
endpoint.getConfiguration().setAgent(...) post-start). Move the resolution
and
the clear error to process(): re-resolve from the endpoint configuration
when no
agent/agentFactory is set, and throw a descriptive IllegalArgumentException
instead of an opaque NullPointerException only when nothing can be resolved.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_011y1gCrVvA3FowKoRM9EvmT
Signed-off-by: Andrea Cosentino <[email protected]>
---------
Signed-off-by: Andrea Cosentino <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
---
.../agent/LangChain4jAgentProducer.java | 12 +++++
.../agent/LangChain4jAgentMissingAgentTest.java | 60 ++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
index 97aa2560e81b..5dbd4b6fecc1 100644
---
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
+++
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
@@ -164,6 +164,18 @@ public class LangChain4jAgentProducer extends
DefaultProducer {
String tags = endpoint.getConfiguration().getTags();
Agent agent = agentFactory != null ?
agentFactory.createAgent(exchange) : this.agent;
+ if (agent == null && agentFactory == null) {
+ // Support an agent configured on the endpoint after the route
started, and give a clear error
+ // instead of an opaque NullPointerException when nothing resolves
to an agent.
+ agent = endpoint.getConfiguration().getAgent();
+ if (agent == null) {
+ throw new IllegalArgumentException(
+ "No agent could be resolved for endpoint " +
endpoint.getEndpointUri()
+ + ". Configure 'agent',
'agentConfiguration' or 'agentFactory', or bind a bean named '"
+ + endpoint.getAgentId() +
"' of type " + Agent.class.getName()
+ + " in the registry.");
+ }
+ }
AiAgentBody<?> aiAgentBody =
exchange.getMessage().getMandatoryBody(AiAgentBody.class);
diff --git
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentMissingAgentTest.java
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentMissingAgentTest.java
new file mode 100644
index 000000000000..76c2549429d9
--- /dev/null
+++
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentMissingAgentTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+package org.apache.camel.component.langchain4j.agent;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.langchain4j.agent.api.AiAgentBody;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class LangChain4jAgentMissingAgentTest {
+
+ @Test
+ void missingAgentReportsAClearError() throws Exception {
+ try (DefaultCamelContext context = new DefaultCamelContext()) {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() {
+ // No agent / agentConfiguration / agentFactory, and no
registry bean named "noSuchAgent".
+ from("direct:x").to("langchain4j-agent:noSuchAgent");
+ }
+ });
+ context.start();
+
+ Exchange result = context.createProducerTemplate()
+ .request("direct:x", e -> e.getIn().setBody(new
AiAgentBody<>("hello")));
+
+ Throwable cause = result.getException();
+ assertNotNull(cause, "an error was expected");
+ boolean clearError = false;
+ while (cause != null) {
+ if (cause instanceof IllegalArgumentException &&
cause.getMessage() != null
+ && cause.getMessage().contains("No agent could be
resolved")) {
+ clearError = true;
+ break;
+ }
+ cause = cause.getCause();
+ }
+ assertTrue(clearError, "expected a clear 'No agent could be
resolved' IllegalArgumentException, got: "
+ + result.getException());
+ }
+ }
+}