{"record":{"id":"01d0b565d73e877f","repo":"alibaba/nacos","slug":"invalid-agent-version-contentdigest","errorCode":null,"errorMessage":"Invalid Agent Version contentDigest","messagePattern":"Invalid Agent Version contentDigest","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/agent/storage/AgentVersionStorageDescriptorSerializer.java","lineNumber":166,"sourceCode":"     *\n     * @param descriptor storage descriptor\n     * @throws IllegalArgumentException when the descriptor is invalid\n     */\n    public static void validate(AgentVersionStorageDescriptor descriptor) {\n        if (descriptor == null) {\n            throw new IllegalArgumentException(\"Agent Version storage descriptor must not be null\");\n        }\n        String provider = descriptor.getProvider();\n        if (provider == null || provider.length() > MAX_PROVIDER_LENGTH\n            || !PROVIDER_PATTERN.matcher(provider).matches()) {\n            throw new IllegalArgumentException(\"Invalid Agent Version storage provider\");\n        }\n        validateRequiredText(\"key\", descriptor.getKey(), MAX_KEY_LENGTH);\n        validateOptionalText(\"keyFormat\", descriptor.getKeyFormat(), MAX_FORMAT_LENGTH);\n        validateOptionalText(\"agentNameCodec\", descriptor.getAgentNameCodec(), MAX_FORMAT_LENGTH);\n        if (descriptor.getContentDigest() == null\n            || !DIGEST_PATTERN.matcher(descriptor.getContentDigest()).matches()) {\n            throw new IllegalArgumentException(\"Invalid Agent Version contentDigest\");\n        }\n        if (!AGENT_VERSION_MEDIA_TYPE.equals(descriptor.getMediaType())) {\n            throw new IllegalArgumentException(\"Agent Version mediaType must be \"\n                + AGENT_VERSION_MEDIA_TYPE);\n        }\n        if (!Integer.valueOf(SCHEMA_VERSION).equals(descriptor.getSchemaVersion())) {\n            throw new IllegalArgumentException(\"Agent Version storage schemaVersion must be \"\n                + SCHEMA_VERSION);\n        }\n        Long size = descriptor.getSize();\n        if (size == null || size < 0 || size > MAX_CONTENT_SIZE) {\n            throw new IllegalArgumentException(\n                \"Agent Version storage size must be between 0 and \" + MAX_CONTENT_SIZE);\n        }\n        if (NACOS_CONFIG_PROVIDER.equals(provider)) {\n            if (!NACOS_CONFIG_KEY_FORMAT.equals(descriptor.getKeyFormat())) {\n                throw new IllegalArgumentException(\"nacos_config keyFormat must be \"\n                    + NACOS_CONFIG_KEY_FORMAT);","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/agent/storage/AgentVersionStorageDescriptorSerializer.java#L148-L184","documentation":"The contentDigest field is null or does not match sha256:[0-9a-f]{64}: exactly the prefix 'sha256:' followed by 64 lowercase hexadecimal digits. Any deviation (uppercase hex, wrong length, missing prefix, different algorithm) is rejected.","triggerScenarios":"validate()/serialize() on a descriptor whose digest is null, uses uppercase hex (sha256:ABCDEF...), has fewer/more than 64 digits, lacks the sha256: prefix, or names a different hash. Fires on corrupted rows too.","commonSituations":"Digest computed with uppercase hex output; a truncated or wrong-length hash; a different algorithm (md5/sha1); a manually typed digest.","solutions":["Compute the digest via AgentVersionContentSerializer.digest(bytes), which produces the correct sha256:<64 lowercase hex> format","Ensure lowercase hex and exactly 64 digits after the prefix","Never hand-type the digest; always derive it from the serialized content bytes"],"exampleFix":"// before\ndescriptor.setContentDigest(\"sha256:ABCDEF...\");\n// after\ndescriptor.setContentDigest(AgentVersionContentSerializer.digest(contentBytes));","handlingStrategy":"validation","validationCode":"private static final Pattern DIGEST = Pattern.compile(\"sha256:[0-9a-f]{64}\");\nString digest = descriptor.getContentDigest();\nif (digest == null || !DIGEST.matcher(digest).matches()) {\n    throw new IllegalArgumentException(\"contentDigest must be sha256:<64 lowercase hex>\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always derive the digest via AgentVersionContentSerializer.digest(bytes)","Never hand-type or uppercase the digest"],"tags":["java","nacos","ai-agent","validation","crypto","sha256","storage-descriptor"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}