conductor-oss/conductor · error · IllegalArgumentException
Skill package contains duplicate path: {path}
Error message
Skill package contains duplicate path: {path} What it means
Thrown by parseSkillPackage when two zip entries normalize to the same path. normalizeEntryName converts backslashes to slashes and strips leading './', so entries like 'foo/./bar' and 'foo/bar', or 'a\\b' and 'a/b', collide. This is a package integrity check preventing ambiguous content.
Source
Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java:442
@SuppressWarnings("unchecked")
private ParsedSkillPackage parseSkillPackage(byte[] bytes, Map<String, Object> manifest) {
List<SkillFileEntry> files = new ArrayList<>();
Map<String, byte[]> contentByPath = new TreeMap<>();
long totalUncompressedBytes = 0;
try (ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(bytes))) {
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
if (entry.isDirectory()) {
continue;
}
if (files.size() >= maxFileCount) {
throw new IllegalArgumentException(
"Skill package exceeds max file count of " + maxFileCount);
}
String path = normalizeEntryName(entry.getName());
if (contentByPath.containsKey(path)) {
throw new IllegalArgumentException(
"Skill package contains duplicate path: " + path);
}
MessageDigest digest = MessageDigest.getInstance("SHA-256");
long size = 0;
ByteArrayOutputStream content = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int read;
while ((read = zip.read(buffer)) >= 0) {
digest.update(buffer, 0, read);
content.write(buffer, 0, read);
size += read;
totalUncompressedBytes += read;
if (size > maxPackageBytes) {
throw new IllegalArgumentException(
"Skill package contains oversized file: " + path);
}
if (totalUncompressedBytes > maxUncompressedBytes) {
throw new IllegalArgumentException(View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Rebuild the zip ensuring each logical path appears exactly once with forward slashes and no './' prefix.
- On Windows, use a zip tool that normalizes to forward slashes, or normalize paths in the build script.
- List the zip contents (unzip -l) and dedupe before uploading.
Example fix
# before: zip contains both ./SKILL.md and SKILL.md # after: rebuild without path prefixes zip skill.zip SKILL.md scripts/run.sh references/doc.md
Defensive patterns
Strategy: validation
Validate before calling
// Before uploading, detect duplicate normalized paths
Set<String> seen = new HashSet<>();
try (var z = new ZipFile(packageFile)) {
for (var e : Collections.list(z.entries())) {
if (e.isDirectory()) continue;
String norm = e.getName().replace('\\','/').replaceAll("^\\./", "");
if (!seen.add(norm)) throw new IllegalStateException("duplicate path: " + norm);
}
} Type guard
static boolean noDuplicatePaths(java.io.File zip) throws java.io.IOException {
Set<String> seen = new HashSet<>();
try (var z = new ZipFile(zip)) {
for (var e : Collections.list(z.entries())) {
if (e.isDirectory()) continue;
if (!seen.add(e.getName().replace('\\','/').replaceAll("^\\./",""))) return false;
}
}
return true;
} Try / catch
try { skillRegistryService.register(manifest, pkg); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("duplicate path")) { /* rebuild zip with unique paths */ }
else throw e;
} Prevention
- Build zips on POSIX paths and never prefix entries with './'.
- List zip contents (unzip -l) and dedupe before uploading.
When it happens
Trigger: POST /api/skills/register with a zip that contains both 'SKILL.md' and './SKILL.md', or 'scripts\run.sh' alongside 'scripts/run.sh'. Also when a zip tool emits a path twice with different separators.
Common situations: Building the zip on Windows producing backslash paths mixed with forward slashes; a packaging script that adds a './' prefix to some entries; zipping the same file from two source locations into the same target path.
Related errors
- Invalid skill package zip: {e.getMessage()}
- Skill package is missing SKILL.md
- Skill package exceeds max file count of {maxFileCount}
- Skill package contains oversized file: {path}
- Skill package contains duplicate script tool name: {toolName
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/a61dad6494c813f8.
Report an issue: GitHub.