alibaba/nacos · error · IllegalArgumentException
Agent Version must not contain read-only projection fields
Error message
Agent Version must not contain read-only projection fields
What it means
An AgentVersionDetail submitted for online creation must not include read-only server-managed projection fields: contentDigest, createTime, or updateTime. These are computed and assigned by the server during persistence; accepting client-supplied values would let callers forge digests or timestamps.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/AgentPersistenceService.java:1073
}
AgentValidationUtils.validateVersion(version.getVersion());
if (version.getCallInterfaces() == null) {
throw new IllegalArgumentException("Online Agent Version must contain callInterfaces");
}
if (version.getNamespaceId() != null
&& !namespaceId.equals(version.getNamespaceId())) {
throw new IllegalArgumentException("Agent Version namespaceId does not match request");
}
if (version.getAgentName() != null && !agentName.equals(version.getAgentName())) {
throw new IllegalArgumentException("Agent Version agentName does not match request");
}
if (version.getStatus() != null
&& !AiConstants.Agent.VERSION_STATUS_ONLINE.equals(version.getStatus())) {
throw new IllegalArgumentException("Agent Version status must be online");
}
if (version.getContentDigest() != null || version.getCreateTime() != null
|| version.getUpdateTime() != null) {
throw new IllegalArgumentException(
"Agent Version must not contain read-only projection fields");
}
if (preferredLatest != null && !version.getVersion().equals(preferredLatest)) {
throw new IllegalArgumentException("preferredLatest must target the created Version");
}
}
private void validateAgentUpdateInputs(Agent replacement) {
if (replacement == null) {
throw new IllegalArgumentException("Agent replacement must not be null");
}
AgentValidationUtils.validateNamespaceId(replacement.getNamespaceId());
AgentValidationUtils.validateAgentName(replacement.getAgentName());
if (replacement.getVersionInfo() != null || replacement.getVersionCatalog() != null
|| replacement.getMetaVersion() != null || replacement.getCreateTime() != null
|| replacement.getUpdateTime() != null) {
throw new IllegalArgumentException(
"Agent update input must not contain read-only projection fields");View on GitHub (pinned to 9b989acdf1)
Solutions
- Set version.setContentDigest(null), version.setCreateTime(null), version.setUpdateTime(null) before calling createOnlineVersion.
- Build the Version detail from scratch using only writable fields rather than copying a read projection.
- Use the toOnlineVersion(request) factory which omits all read-only fields.
Example fix
// before — read-only fields carried over from a GET response
version.setContentDigest("sha256:abc...");
version.setCreateTime(1700000000L);
persistenceService.createOnlineVersion(ns, name, version, null); // throws
// after — clear server-managed fields
version.setContentDigest(null);
version.setCreateTime(null);
version.setUpdateTime(null);
persistenceService.createOnlineVersion(ns, name, version, null); Defensive patterns
Strategy: validation
Validate before calling
if (version.getContentDigest() != null || version.getCreateTime() != null || version.getUpdateTime() != null) {
throw new IllegalArgumentException("Version detail must not carry read-only projection fields");
} Type guard
boolean hasNoProjectionFields(AgentVersionDetail v) {
return v.getContentDigest() == null && v.getCreateTime() == null && v.getUpdateTime() == null;
} Prevention
- Never reuse a Version detail from a GET response for a create without clearing server fields.
- Treat contentDigest, createTime, updateTime as strictly server-assigned.
- Prefer toOnlineVersion(request) which never sets projection fields.
When it happens
Trigger: Calling createOnlineVersion with an AgentVersionDetail where getContentDigest(), getCreateTime(), or getUpdateTime() returns a non-null value. This happens when a Version detail read from a GET response is reused for a create call without clearing these fields.
Common situations: A client fetches an existing Version, modifies callInterfaces, and re-submits it as a new online Version without nulling contentDigest/createTime/updateTime. An import tool preserves timestamps from the source system.
Related errors
- Online Agent Version must contain callInterfaces
- Agent Version namespaceId does not match request
- Agent Version agentName does not match request
- Agent Version status must be online
- preferredLatest must target the created Version
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/cfade3b7d9af1a87.
Report an issue: GitHub.