conductor-oss/conductor · error · IllegalArgumentException
Skill package not found: {name}@{version}
Error message
Skill package not found: {name}@{version} What it means
Thrown by packageBytes when a SkillDetail has a null or blank `packageFileHandleId` — the opaque ID used to read the stored package blob from the SkillPackageStore. The metadata record exists, but the blob it points at is missing, so any operation that needs the actual zip bytes (download, file listing, repackaging) refuses rather than returning garbage.
Source
Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java:897
return matcher.group(2).trim();
}
private boolean packageExists(SkillDetail detail) {
String handle = detail.getPackageFileHandleId();
if (handle == null || handle.isBlank()) {
return false;
}
try {
return packageStore.exists(handle);
} catch (RuntimeException ignored) {
return false;
}
}
private byte[] packageBytes(SkillDetail detail) {
String handle = detail.getPackageFileHandleId();
if (handle == null || handle.isBlank()) {
throw new IllegalArgumentException(
"Skill package not found: " + detail.getName() + "@" + detail.getVersion());
}
return packageStore.read(handle);
}
private void deletePackage(SkillDetail detail) {
String handle = detail.getPackageFileHandleId();
if (handle != null && !handle.isBlank()) {
try {
packageStore.delete(handle);
} catch (IllegalArgumentException ignored) {
// Legacy records used synthetic handles before the package store existed.
}
}
}
private String normalizeEntryName(String name) {
String normalized = name.replace('\\', '/');View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Re-upload the skill package so a fresh blob handle is written and the metadata row's packageFileHandleId is populated.
- If this is a legacy record, delete the orphan metadata row and re-publish.
- Verify the SkillPackageStore backend is reachable and the DAO write path sets the handle on insert.
Example fix
// before: metadata row with packageFileHandleId = null // re-publish via the upload API POST /api/ai/skills/packages (multipart with the corrected zip) // after: row carries a real handle id and packageBytes() resolves
Defensive patterns
Strategy: validation
Validate before calling
// Verify a skill has a non-blank package handle before using it.
boolean hasStoredPackage(SkillDetail d) {
String h = d.getPackageFileHandleId();
return h != null && !h.isBlank();
} Type guard
boolean isResolvable(SkillDetail d, SkillPackageStore store) {
String h = d.getPackageFileHandleId();
return h != null && !h.isBlank() && store.exists(h);
} Try / catch
try {
byte[] bytes = skillRegistry.packageBytes(detail);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Skill package not found")) {
return notFound(e.getMessage()); // 404, prompt re-upload
}
throw e;
} Prevention
- Re-upload skills after a store migration and verify packageFileHandleId is set.
- Run a consistency check (metadata row -> blob exists) periodically.
- Treat a missing handle as a data-integrity incident; do not silently skip.
When it happens
Trigger: Calling an API that materializes package bytes (download, list files, read file content) for a skill whose metadata row survived but whose blob was deleted, never written, or migrated incompletely from the legacy synthetic-handle scheme.
Common situations: Partial migration from pre-package-store records; the underlying object store was cleared but the DAO table was not; a delete partially failed and left the metadata row; a manually-inserted test row omitted the handle.
Related errors
- Registered agent definition is missing metadata.agentDef: ${
- Skill manifest name '{manifestName}' does not match package
- Skill {name} version {version} already exists with a differe
- File path is required
- Skill file is too large to preview: {cleanPath}
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/16c267cb72b06691.
Report an issue: GitHub.