alibaba/nacos · error · NacosApiException
INVALID_PARAM
INVALID_PARAM
Error message
AbstractNacosAgentDiscoveryListener must not be null.
What it means
Thrown by NacosAgentDiscoveryCacheHolder.subscribe when the caller passes a null listener. Subscribe ties an agent reference to a listener identity that receives periodic Discover snapshots, so a null listener makes the subscription meaningless and is rejected up front with INVALID_PARAM. This is a programmer-contract guard, not a transient runtime condition.
Source
Thrown at client/src/main/java/com/alibaba/nacos/client/ai/cache/NacosAgentDiscoveryCacheHolder.java:109
this.updateIntervalMillis = updateIntervalMillis;
this.pollingExecutor = pollingExecutor;
this.callbackExecutor = callbackExecutor;
}
/**
* Subscribe by periodically executing the same Discover request.
*
* @param reference Agent reference
* @param filter optional filter
* @param listener listener identity
* @return current snapshot, or {@code null} when absent
* @throws NacosException when validation or the initial Discover fails
*/
public synchronized AgentDiscoveryResult subscribe(AgentReference reference,
AgentDiscoveryFilter filter, AbstractNacosAgentDiscoveryListener listener)
throws NacosException {
if (listener == null) {
throw new NacosApiException(NacosException.INVALID_PARAM,
ErrorCode.PARAMETER_VALIDATE_ERROR,
"AbstractNacosAgentDiscoveryListener must not be null.");
}
AgentDiscoveryRequest request =
AgentModelUtils.copyDiscoveryRequest(reference, filter, namespaceId);
SubscriptionKey key = new SubscriptionKey(buildRequestKey(request), listener);
Subscription existing = subscriptions.get(key);
if (existing != null) {
return AgentModelUtils.copyDiscoveryResult(existing.current);
}
AgentDiscoveryResult current = discoverOrNull(request);
Subscription subscription = new Subscription(key, request, listener, current);
subscriptions.put(key, subscription);
schedule(subscription);
return AgentModelUtils.copyDiscoveryResult(current);
}
/**View on GitHub (pinned to 9b989acdf1)
Solutions
- Ensure the listener passed to subscribeAgent / NacosAgentDiscoveryCacheHolder.subscribe is non-null before the call.
- If the listener is optional in your flow, guard it locally and skip subscribing when it is null.
- Check the code path that creates the listener for silent null returns (factory methods, bean lookups).
Example fix
// before
service.subscribeAgent(reference, filter, listener); // listener may be null
// after
if (listener != null) {
service.subscribeAgent(reference, filter, listener);
} else {
LOGGER.warn("Skipping agent discovery subscribe: listener is null for {}", reference);
} Defensive patterns
Strategy: validation
Validate before calling
if (listener == null) {
throw new IllegalArgumentException("listener must not be null for agent discovery subscribe");
}
service.subscribeAgent(reference, filter, listener); Type guard
Objects.requireNonNull(listener, "listener"); // or explicit null check before subscribe
Prevention
- Treat the listener as a required argument and validate it at the call boundary.
- Use @NonNull annotations/static analysis to catch null listener arguments at compile time.
- Initialize listener fields before calling subscribe.
When it happens
Trigger: Calling NacosAiService.subscribeAgent(reference, filter, null) or otherwise invoking the cache holder's subscribe(...) with a listener argument that resolved to null (e.g. a listener field not yet initialized, a Map lookup that returned null).
Common situations: Listener registered lazily but subscribe called before assignment; DI/lookup of the listener bean failed silently and returned null; refactored call site that dropped the listener argument.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/cfb124ab75d281af.
Report an issue: GitHub.