conductor-oss/conductor · error · IllegalArgumentException

Skill {name} version {version} already exists with a differe

Error message

Skill {name} version {version} already exists with a different checksum

What it means

Thrown by register() when a skill with the same name AND version already exists in the metadata store, but the uploaded package's SHA-256 checksum differs from the stored record. This is idempotency protection: a name+version pair is immutable once stored. Re-uploading identical bytes is allowed (and re-stores the package if missing), but different bytes under the same version is rejected.

Source

Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java:175

                            + "' does not match package SKILL.md name '"
                            + name
                            + "'");
        }

        String version = stringValue(manifest.get("version"));
        if (version == null || version.isBlank()) {
            version = checksum.substring(0, 12);
        }
        validateVersion(version);
        pinRegisteredCrossSkillRefs(rawConfig);

        long now = Instant.now().toEpochMilli();

        Optional<SkillDetail> existingOpt = metadataDao.find(name, version);
        if (existingOpt.isPresent()) {
            SkillDetail existing = existingOpt.get();
            if (!checksum.equals(existing.getChecksum())) {
                throw new IllegalArgumentException(
                        "Skill "
                                + name
                                + " version "
                                + version
                                + " already exists with a different checksum");
            }
            if (!packageExists(existing)) {
                StoredSkillPackage restored = packageStore.store(name, version, checksum, bytes);
                existing.setPackageFileHandleId(restored.handle());
                existing.setStorageType(restored.storageType());
                existing.setPackageSize(restored.size());
                existing.setUpdatedAt(now);
                metadataDao.save(existing, false);
            }
            return existing;
        }

        StoredSkillPackage stored = null;

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Bump the version field in the manifest (e.g. 1.0.0 -> 1.0.1) so the new content gets a distinct version slot.
  2. If you intended to replace the existing content, delete the old version first: DELETE /api/skills/{name}/versions/{version}, then re-register.
  3. If the new upload should be identical, confirm the zip bytes are unchanged — re-export from the same source the original used.

Example fix

// before: register name=foo version=1.0.0 checksum=aaa... then again with checksum=bbb...
// after — bump version on the second upload:
{"name":"foo","version":"1.0.1"}
Defensive patterns

Strategy: validation

Validate before calling

// Before register, check whether name+version exists and whether the checksum differs
byte[] bytes = pkg.getBytes();
String checksum = sha256Hex(bytes);
Optional<SkillDetail> existing = metadataDao.find(name, version); // if you have DAO access
if (existing.isPresent() && !checksum.equals(existing.get().getChecksum())) {
    // bump version or delete first
}

Type guard

// Client-side: is this version safe to (re)upload?
boolean safeToUpload(String name, String version, String localChecksum, SkillRegistryClient c) {
    try { return localChecksum.equals(c.get(name, version).getChecksum()); }
    catch (RuntimeException notFound) { return true; }
}

Try / catch

try { skillRegistryService.register(manifest, pkg); }
catch (IllegalArgumentException e) {
    if (e.getMessage().contains("already exists with a different checksum")) {
        // bump version in manifest and retry, or DELETE then re-register
    } else throw e;
}

Prevention

When it happens

Trigger: POST /api/skills/register twice with name=foo version=1.0.0 but different zip contents. Common when version is pinned explicitly in the manifest and the zip was rebuilt with changed files between uploads.

Common situations: Forgetting to bump the version after editing skill files; re-running a deploy pipeline that hardcodes a version string; two teams pushing the same version number for different content.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/f2768ca8ea3f8f1b. Report an issue: GitHub.