conductor-oss/conductor · error · NonRetryableException
agentUrl must not be blank
Error message
agentUrl must not be blank
What it means
Thrown by A2AWorkers.resolveRemoteEndpoint as NonRetryableException when the configured URL trims to null. resolveRemoteEndpoint is called from the AGENT, CANCEL_AGENT, and cancel() paths after agentType validation passes, to map a discovery/card URL to the JSON-RPC endpoint. A blank agentUrl at this stage is terminal (non-retryable).
Source
Thrown at ai/src/main/java/org/conductoross/conductor/ai/tasks/worker/A2AWorkers.java:352
} finally {
recordOutcome(result);
}
}
/**
* Resolves the JSON-RPC endpoint while keeping the configured discovery identity intact.
*
* <p>The workflow editor stores the fetched Agent Card in task metadata. Prefer its advertised
* endpoint so a task configured with a website or well-known card URL does not POST JSON-RPC to
* the discovery document. API-authored workflows without a snapshot still support direct Agent
* Card URLs by discovering the endpoint at execution time. Direct endpoint URLs remain valid
* and all returned values are trimmed before the SSRF-guarded A2A service uses them.
*/
private String resolveRemoteEndpoint(
Task task, String configuredUrl, Map<String, String> headers) {
String configured = StringUtils.trimToNull(configuredUrl);
if (configured == null) {
throw new NonRetryableException("agentUrl must not be blank");
}
String snapshottedEndpoint = endpointFromSnapshot(task);
if (snapshottedEndpoint != null) {
return snapshottedEndpoint;
}
String pathWithoutQuery = StringUtils.substringBefore(configured, "?");
if (StringUtils.endsWithIgnoreCase(pathWithoutQuery, ".json")) {
AgentCard card = a2aService.getAgentCard(configured, headers);
String discoveredEndpoint = card == null ? null : StringUtils.trimToNull(card.getUrl());
if (discoveredEndpoint == null) {
throw new NonRetryableException(
"Agent Card resolved from "
+ configured
+ " does not advertise a JSON-RPC 'url'");
}
return discoveredEndpoint;View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Ensure 'agentUrl' is present and non-blank on AGENT and CANCEL_AGENT task inputs.
- When propagating cancellation, forward the original agentUrl or rely on the snapshotted endpoint in task metadata.
- Validate the agentUrl input at workflow authoring time.
- If the URL is discovered from an Agent Card (.json), confirm the card advertises a non-blank 'url' field.
Example fix
// before
A2ACallRequest req = ...; // agentUrl is null/whitespace
String endpoint = resolveRemoteEndpoint(task, req.getAgentUrl(), headers); // throws
// after
if (StringUtils.isBlank(req.getAgentUrl())) {
// surface a clear validation error before resolving
throw new IllegalArgumentException("agentUrl is required for remote A2A calls");
}
String endpoint = resolveRemoteEndpoint(task, req.getAgentUrl(), headers); Defensive patterns
Strategy: validation
Validate before calling
if (StringUtils.isBlank(request.getAgentUrl())) {
throw new IllegalArgumentException(
"AGENT/CANCEL_AGENT requires a non-blank 'agentUrl'");
} Try / catch
// NonRetryableException is terminal; validate before calling resolveRemoteEndpoint.
try {
workers.agent(request);
} catch (NonRetryableException e) {
if (e.getMessage().contains("agentUrl must not be blank")) {
// fix the task input; do not retry
}
} Prevention
- Always include a non-blank 'agentUrl' on AGENT and CANCEL_AGENT task inputs.
- Forward the original agentUrl when propagating cancellations.
- Ensure snapshotted endpoint metadata is present for resolved agents.
- Validate agentUrl is non-blank before the task is scheduled.
When it happens
Trigger: An AGENT or CANCEL_AGENT task where agentUrl is empty/whitespace and no snapshotted endpoint exists in task metadata; reached when resolving the remote endpoint to send/cancel the A2A message. Note executeRemote checks agentUrl blank earlier (line 311) and fail()s, but resolveRemoteEndpoint is also invoked from cancelAgent (line 250) and the TaskCancellationHandler.cancel() path (line 281) where this guard fires.
Common situations: A CANCEL_AGENT or cancellation propagation path where the original agentUrl was not stored/forwarded, a dynamically-resolved agentUrl that came back empty, or task metadata lacking a snapshotted a2a agentCard url.
Related errors
- GET_AGENT_CARD requires 'agentUrl'
- agentUrl must not be blank
- agentUrl must use http or https, got: {scheme}
- agentUrl resolves to a cloud metadata address — SSRF blocked
- agentUrl resolves to a private/reserved address — SSRF block
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/cde970ac89c5a9a6.
Report an issue: GitHub.