alibaba/nacos · warning · NacosApiException
20002
20002
Error message
Invalid version from {source}: '{version}', expected x.y.z or vN What it means
An INVALID_PARAM (HTTP 400, ErrorCode PARAMETER_VALIDATE_ERROR/20002) from validateUploadVersionFormat: the version resolved from a source (SKILL.md YAML front-matter, or _meta.json inside the ZIP) is not a supported format. Supported formats are full semantic version x.y.z (e.g. 1.0.0) or the legacy vN form (e.g. v3). Short forms like 1.0 are only accepted on the lenient/normalized path, not the strict validation path.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/skills/SkillOperationServiceImpl.java:690
SkillResource metaResource = skill.getResource().get(resourceId);
if (metaResource == null || StringUtils.isBlank(metaResource.getContent())) {
return null;
}
try {
@SuppressWarnings("unchecked")
Map<String, Object> meta = JacksonUtils.toObj(metaResource.getContent(), Map.class);
Object version = meta == null ? null : meta.get("version");
return version == null ? null : StringUtils.trim(String.valueOf(version));
} catch (Exception e) {
LOGGER.warn("Failed to resolve version from skill _meta.json: {}", e.getMessage());
return null;
}
}
private static String validateUploadVersionFormat(String version, String source)
throws NacosApiException {
if (!VersionUtils.isSupportedVersionFormat(version)) {
throw new NacosApiException(NacosException.INVALID_PARAM,
ErrorCode.PARAMETER_VALIDATE_ERROR,
"Invalid version from " + source + ": '" + version
+ "', expected x.y.z or vN");
}
return version;
}
private static UploadVersionCandidate buildLenientUploadVersionCandidate(String version,
String source) {
String candidate = StringUtils.trim(version);
if (VersionUtils.isSupportedVersionFormat(candidate)) {
return new UploadVersionCandidate(candidate, source);
}
String normalizedVersion = normalizeShortSemverVersion(candidate);
if (normalizedVersion != null) {
return UploadVersionCandidate.normalized(normalizedVersion, source, candidate);
}
return UploadVersionCandidate.invalid(candidate, source);View on GitHub (pinned to 9b989acdf1)
Solutions
- Set the version to a full x.y.z value (e.g. 1.0.0) or a vN value (e.g. v3) in SKILL.md front-matter and/or _meta.json.
- Remove the version field to let the server fall back to the default 0.0.1 / auto-increment.
- Re-zip and re-upload.
Example fix
// before — SKILL.md front-matter --- name: weather-tool version: 1.0 --- // after --- name: weather-tool version: 1.0.0 ---
Defensive patterns
Strategy: validation
Validate before calling
// Validate the declared version format before uploading.
String v = resolveVersionFromFrontmatter(skillMd);
if (StringUtils.isNotBlank(v) && !VersionUtils.isSupportedVersionFormat(v)) {
// ask the author to use x.y.z or vN (or remove the field for default 0.0.1)
} Prevention
- Use full semver x.y.z (1.0.0) or vN (v3) in SKILL.md front-matter and _meta.json.
- Avoid short forms (1.0), tags (latest), or date-based versions for the strict path.
- Omit the version field to let the server default/auto-increment.
When it happens
Trigger: Uploading a skill whose front-matter / _meta.json declares a version like '1.0', 'latest', a date, or any non-x.y.z/non-vN string, when the strict version resolution path is taken.
Common situations: Author used a short semver (1.0 / 1) expecting it to be accepted; used a tag like 'latest' or 'stable'; non-numeric or date-based versioning.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/d069a7fa640b490c.
Report an issue: GitHub.