alibaba/nacos · error · IllegalArgumentException
Skill name cannot be blank
Error message
Skill name cannot be blank
What it means
SkillUtils.toZipBytes throws IllegalArgumentException when the Skill object is non-null but its getName() returns a blank value. The skill name is used as the root directory in the ZIP structure (skillName/SKILL.md), so it must be a valid non-blank identifier.
Source
Thrown at api/src/main/java/com/alibaba/nacos/api/ai/model/skills/SkillUtils.java:115
/**
* Convert Skill object to a ZIP byte array containing all skill files.
*
* <p>The ZIP structure mirrors the upload format:
* {@code skillName/SKILL.md}, {@code skillName/type/resourceName}, etc.
* Binary resources (marked with metadata encoding=base64) are decoded back to raw bytes.</p>
*
* @param skill the Skill object to convert
* @return ZIP file as byte array
* @throws IOException if ZIP creation fails
* @throws IllegalArgumentException if skill is null or skill name is blank
*/
public static byte[] toZipBytes(Skill skill) throws IOException {
if (skill == null) {
throw new IllegalArgumentException("Skill cannot be null");
}
if (StringUtils.isBlank(skill.getName())) {
throw new IllegalArgumentException("Skill name cannot be blank");
}
String skillName = skill.getName();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
// 1. SKILL.md
zos.putNextEntry(new ZipEntry(skillName + "/SKILL.md"));
zos.write(toMarkdown(skill).getBytes(StandardCharsets.UTF_8));
zos.closeEntry();
// 2. Resource files
if (skill.getResource() != null && !skill.getResource().isEmpty()) {
for (SkillResource resource : skill.getResource().values()) {
if (resource == null || StringUtils.isBlank(resource.getName())) {
continue;
}
String entryPath = buildZipEntryPath(skillName, resource);
zos.putNextEntry(new ZipEntry(entryPath));View on GitHub (pinned to 9b989acdf1)
Solutions
- Validate skill.getName() is non-blank before calling toZipBytes.
- Enforce name presence at the Skill builder or constructor level.
- Return a validation error to the API caller when name is missing.
Example fix
// before
Skill skill = new Skill();
skill.setResource(resources);
// name never set
byte[] zip = SkillUtils.toZipBytes(skill); // throws
// after
Skill skill = new Skill();
skill.setName("my-skill");
skill.setResource(resources);
byte[] zip = SkillUtils.toZipBytes(skill); // ok Defensive patterns
Strategy: validation
Validate before calling
if (skill == null || StringUtils.isBlank(skill.getName())) {
throw new IllegalArgumentException("Skill name is required");
}
byte[] zip = SkillUtils.toZipBytes(skill); Type guard
public static boolean hasValidSkillName(Skill skill) {
return skill != null && skill.getName() != null && !skill.getName().trim().isEmpty();
} Try / catch
try {
byte[] zip = SkillUtils.toZipBytes(skill);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Skill name cannot be blank")) {
return badRequest("Skill name is required");
}
throw e;
} Prevention
- Enforce name presence at Skill construction or builder level.
- Validate deserialized Skill objects before processing.
- Reject skill uploads without a valid name at the API boundary.
When it happens
Trigger: Calling toZipBytes with a Skill whose name field is null, empty, or whitespace. Happens when a Skill object is partially constructed or deserialized from JSON that omits the name field.
Common situations: A Skill object built from a request body where the name field was absent. A deserialized Skill from a malformed config. A test fixture that forgot to set the name.
Related errors
- Skill cannot be null
- PARAMETER_MISSING
- PARAMETER_VALIDATE_ERROR
- PARAMETER_MISSING
- PARAMETER_VALIDATE_ERROR
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/700dd36f962f98bf.
Report an issue: GitHub.