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.

Solutions

  1. Set version.setContentDigest(null), version.setCreateTime(null), version.setUpdateTime(null) before calling createOnlineVersion.
  2. Build the Version detail from scratch using only writable fields rather than copying a read projection.
  3. 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

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


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/cfade3b7d9af1a87. Report an issue: GitHub.

Appendix: 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)