alibaba/spring-ai-alibaba · error · IllegalStateException

AgentCard.url is empty

Error message

AgentCard.url is empty

What it means

sendMessageToServer resolves the base URL from the AgentCard and refuses to issue an HTTP request when it is null or blank, throwing this IllegalStateException. The A2A client needs the remote agent's endpoint URL to POST the JSON-RPC request.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/a2a/A2aNodeActionWithConfig.java:777

			return template.render(state.data());
		} else if (!shareState || (shareState && state.value("messages").isEmpty())) {
			throw new IllegalStateException("Instruction is empty and shareState is false");
		}
		return "";
	}

	/**
	 * Send the request to the remote A2A server and return the non-streaming response.
	 * @param agentCard Agent card (source for server URL/metadata)
	 * @param requestPayload JSON string payload built by buildSendMessageRequest
	 * @return Response body as string
	 */
	private String sendMessageToServer(AgentCardWrapper agentCard, String requestPayload) throws Exception {
		String baseUrl = resolveAgentBaseUrl(agentCard);
		System.out.println(baseUrl);
		System.out.println(requestPayload);
		if (baseUrl == null || baseUrl.isBlank()) {
			throw new IllegalStateException("AgentCard.url is empty");
		}

		try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
			HttpPost post = new HttpPost(baseUrl);
			post.setHeader("Content-Type", "application/json");
			post.setEntity(new StringEntity(requestPayload, ContentType.APPLICATION_JSON));

			try (CloseableHttpResponse response = httpClient.execute(post)) {
				int statusCode = response.getStatusLine().getStatusCode();
				if (statusCode != 200) {
					throw new IllegalStateException("HTTP request failed, status: " + statusCode);
				}
				HttpEntity entity = response.getEntity();
				if (entity == null) {
					throw new IllegalStateException("Empty HTTP entity");
				}
				return EntityUtils.toString(entity, "UTF-8");
			}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Fix the remote agent's AgentCard so url points at its A2A endpoint
  2. If using Nacos/registry discovery, re-register the service with the correct URL/IP and port
  3. Validate the card before building the node: if (card.url() == null || card.url().isBlank()) fail fast with a clear config error
  4. Pin the URL explicitly in your configuration instead of relying on the card if discovery is unreliable

Example fix

// before
// remote publishes: AgentCard.builder().name("writer").build() // no url
// after
AgentCard card = AgentCard.builder()
    .name("writer")
    .url("http://10.0.0.5:8080/a2a")
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (agentCard.url() == null || agentCard.url().isBlank()) {
    throw new IllegalArgumentException("AgentCard has no url; fix remote registration before invoking");
}

Type guard

boolean hasUrl(AgentCardWrapper c) { return c != null && c.url() != null && !c.url().isBlank(); }

Try / catch

try {
    String resp = action.sendToServer(card, payload);
} catch (IllegalStateException e) {
    // re-resolve agent card from registry or use a configured fallback URL
}

Prevention

When it happens

Trigger: AgentCard.url is not set by the A2A server's agent card response, or resolveAgentBaseUrl returns null/blank (card fetched from a registry like Nacos without a URL, or a misregistered service).

Common situations: Remote agent registered in Nacos without its URL; agent card served by a placeholder/stub; DNS-less or unconfigured deployment where the card was hand-built; older agent publishing a card lacking the url field.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/3707b6440458b460. Report an issue: GitHub.