alibaba/spring-ai-alibaba · error · IllegalStateException

Please use getAgentCard(agentName) first.

Error message

Please use getAgentCard(agentName) first.

What it means

NacosAgentCardProvider supports both a no-arg getAgentCard() and a by-name getAgentCard(agentName). The no-arg variant returns a cached agentCard field; if the caller never invoked the by-name variant (or otherwise populated the cache) the provider throws IllegalStateException instructing the caller to call getAgentCard(agentName) first. This is a usage-order contract: the parameterless accessor only reads a pre-fetched card.

Source

Thrown at spring-boot-starters/spring-ai-alibaba-starter-a2a-nacos/src/main/java/com/alibaba/cloud/ai/a2a/registry/nacos/discovery/NacosAgentCardProvider.java:54

 *
 * @author xiweng.yy
 */
public class NacosAgentCardProvider implements AgentCardProvider {

	private static final Logger LOGGER = LoggerFactory.getLogger(NacosAgentCardProvider.class);

	private final A2aService a2aService;

	private AgentCardWrapper agentCard;

	public NacosAgentCardProvider(A2aService a2aService) {
		this.a2aService = a2aService;
	}

	@Override
	public AgentCardWrapper getAgentCard() {
		if (null == agentCard) {
			throw new IllegalStateException("Please use getAgentCard(agentName) first.");
		}
		return agentCard;
	}

	@Override
	public AgentCardWrapper getAgentCard(String agentName) {
		try {
			AgentCard nacosAgentCard = a2aService.getAgentCard(agentName);
			agentCard = new NacosAgentCardWrapper(AgentCardConverterUtil.convertToA2aAgentCard(nacosAgentCard));
			a2aService.subscribeAgentCard(agentName, new AbstractNacosAgentCardListener() {
				@Override
				public void onEvent(NacosAgentCardEvent event) {
					AgentCard newAgentCard = event.getAgentCard();
					if (LOGGER.isDebugEnabled()) {
						LOGGER.debug("Received new Agent Card: {}", JacksonUtils.toJson(newAgentCard));
					}
					agentCard.setAgentCard(AgentCardConverterUtil.convertToA2aAgentCard(newAgentCard));
				}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Call getAgentCard(agentName) with the target agent's name first, then use the returned card (or call the no-arg getter afterwards).
  2. If you need nameless lookup, query the Nacos registry for available agent names first and pass one to getAgentCard(String).
  3. Inject/configure the AgentCardWrapper so the provider's agentCard field is populated at construction if single-agent mode is intended.
  4. Wrap the no-arg call in try-catch for IllegalStateException and fall back to the by-name API.

Example fix

// before
AgentCardWrapper card = provider.getAgentCard(); // IllegalStateException
// after
AgentCardWrapper card = provider.getAgentCard("my-agent");
Defensive patterns

Strategy: type-guard

Validate before calling

AgentCardWrapper card = provider.getAgentCard(agentName); // fetch first
if (card != null) { /* safe to use card / provider.getAgentCard() */ }

Type guard

AgentCardWrapper safeGetCard(NacosAgentCardProvider p, String name) {
    try { return p.getAgentCard(); }
    catch (IllegalStateException e) { return p.getAgentCard(name); }
}

Try / catch

try {
    card = provider.getAgentCard();
} catch (IllegalStateException e) {
    card = provider.getAgentCard(agentName);
}

Prevention

When it happens

Trigger: Calling getAgentCard() (no arguments) on NacosAgentCardProvider before any successful call to getAgentCard(agentName) has populated the internal agentCard field.

Common situations: Framework or application code that resolves a single agent card from the A2A registry without knowing a name, relying on default discovery while the provider was constructed without an initial card; ordering issues where discovery happens after the card is requested.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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