alibaba/nacos · error · IllegalArgumentException
Agent update input must not contain read-only projection fie
Error message
Agent update input must not contain read-only projection fields
What it means
An Agent replacement for metadata update must not include read-only server-managed projection fields: versionInfo, versionCatalog, metaVersion, createTime, or updateTime. These are derived and maintained by the server; accepting client values would corrupt version tracking and optimistic-concurrency semantics.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/agent/AgentPersistenceService.java:1090
|| 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");
}
}
private Agent normalizeAgentUpdate(Agent source, Agent current) {
Agent result = new Agent();
result.setNamespaceId(source.getNamespaceId());
result.setAgentName(source.getAgentName());
result.setDisplayName(source.getDisplayName());
result.setDescription(source.getDescription());
result.setIconUrl(source.getIconUrl());
result.setProvider(source.getProvider());
result.setTags(source.getTags());
result.setExtensions(source.getExtensions());
result.setStatus(source.getStatus());
result.setOwner(current.getOwner());
result.setScope(current.getScope());
result.setVersionInfo(current.getVersionInfo());View on GitHub (pinned to 9b989acdf1)
Solutions
- Build the update Agent from scratch with only writable fields (namespaceId, agentName, displayName, description, iconUrl, provider, tags, extensions, status, owner, scope).
- Null out versionInfo, versionCatalog, metaVersion, createTime, updateTime on any Agent object before passing it to tryUpdateAgent.
- Use a dedicated AgentUpdateRequest/Form that only exposes writable fields.
Example fix
// before — full projection re-submitted as update
Agent replacement = fetchedAgent; // from GET response
replacement.setDisplayName("New Name");
persistenceService.tryUpdateAgent(replacement, current); // throws
// after — only writable fields
Agent replacement = new Agent();
replacement.setNamespaceId("public");
replacement.setAgentName("my-agent");
replacement.setDisplayName("New Name");
persistenceService.tryUpdateAgent(replacement, current); Defensive patterns
Strategy: validation
Validate before calling
if (replacement.getVersionInfo() != null || replacement.getVersionCatalog() != null
|| replacement.getMetaVersion() != null || replacement.getCreateTime() != null
|| replacement.getUpdateTime() != null) {
throw new IllegalArgumentException("Agent update must not include read-only fields");
} Type guard
boolean hasNoReadOnlyFields(Agent a) {
return a.getVersionInfo() == null && a.getVersionCatalog() == null
&& a.getMetaVersion() == null && a.getCreateTime() == null && a.getUpdateTime() == null;
} Prevention
- Never PUT a full Agent projection from a GET response; send only writable fields.
- Use AgentUpdateRequest/AgentUpdateForm at the API boundary to constrain the payload.
- Treat versionInfo, versionCatalog, metaVersion, createTime, updateTime as server-managed.
When it happens
Trigger: Calling tryUpdateAgent with an Agent whose getVersionInfo(), getVersionCatalog(), getMetaVersion(), getCreateTime(), or getUpdateTime() returns non-null. This happens when a client fetches an Agent via GET and re-submits the full object as an update payload.
Common situations: A client GETs an Agent, modifies displayName, and PUTs the entire object back including versionInfo and timestamps. A generic client SDK serializes all fields on update. A migration tool copies full projections between environments.
Related errors
- Agent Version must not contain read-only projection fields
- Agent replacement must not be null
- Online Agent Version must contain callInterfaces
- Agent Version namespaceId does not match request
- Agent Version agentName does not match request
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/1057d773ed7dc085.
Report an issue: GitHub.