conductor-oss/conductor · error · IllegalArgumentException

Invalid skill manifest JSON: {e.getMessage()}

Error message

Invalid skill manifest JSON: {e.getMessage()}

What it means

Thrown by register() (via parseManifest) when the manifest JSON cannot be parsed by Jackson — the manifest part was non-blank but not valid JSON (or not a JSON object/map). The original IOException from Jackson is attached as the cause.

Source

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

                if (detail.getChecksum() != null && detail.getChecksum().startsWith(version)) {
                    return detail.getVersion();
                }
            }
            return version;
        }
        return metadataDao
                .latestVersion(name)
                .orElseThrow(() -> new IllegalArgumentException("Skill not found: " + name));
    }

    private Map<String, Object> parseManifest(String manifestJson) {
        if (manifestJson == null || manifestJson.isBlank()) {
            throw new IllegalArgumentException("Skill manifest is required");
        }
        try {
            return MAPPER.readValue(manifestJson, MAP_TYPE);
        } catch (IOException e) {
            throw new IllegalArgumentException("Invalid skill manifest JSON: " + e.getMessage(), e);
        }
    }

    private byte[] readPackage(MultipartFile packageFile) {
        try {
            byte[] bytes = packageFile.getBytes();
            if (bytes.length > maxPackageBytes) {
                throw new IllegalArgumentException(
                        "Skill package exceeds max size of " + maxPackageBytes + " bytes");
            }
            return bytes;
        } catch (IOException e) {
            throw new IllegalArgumentException(
                    "Failed to read skill package: " + e.getMessage(), e);
        }
    }

    @SuppressWarnings("unchecked")

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Validate the manifest string with a JSON parser on the client before uploading.
  2. Ensure the manifest is a JSON object (starts with { and ends with }), not an array or scalar.
  3. Check the caused-by message for the exact Jackson parse location (line/column).

Example fix

// before
{"name":"foo", "version":"1.0.0",}
// after (remove trailing comma)
{"name":"foo","version":"1.0.0"}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate JSON on the client before upload
try { new ObjectMapper().readValue(manifestJson, Map.class); }
catch (Exception e) { throw new IllegalArgumentException("manifest is not valid JSON: " + e.getMessage()); }

Type guard

static boolean isValidManifestJson(String json) {
    try { Object o = new ObjectMapper().readValue(json, Object.class); return o instanceof Map; }
    catch (Exception e) { return false; }
}

Try / catch

try { skillRegistryService.register(manifest, pkg); }
catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Invalid skill manifest JSON")) { /* fix JSON, retry */ }
    else throw e;
}

Prevention

When it happens

Trigger: POST /api/skills/register with manifest='{name: foo}' (unquoted), manifest='[1,2,3]' (array, not object), or manifest containing a trailing comma / syntax error. Also a manifest sent as form-encoded key=value instead of raw JSON.

Common situations: Hand-writing manifest JSON without quoting keys; a templating layer producing malformed JSON; sending YAML or form data where raw JSON is expected; encoding issues (BOM, double-escaped quotes).

Related errors


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