{"record":{"id":"6a90babbefe61f99","repo":"conductor-oss/conductor","slug":"skill-manifest-is-required","errorCode":null,"errorMessage":"Skill manifest is required","messagePattern":"Skill manifest is required","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java","lineNumber":402,"sourceCode":"            if (metadataDao.find(name, version).isPresent()) {\n                return version;\n            }\n            // Allow a checksum prefix in place of an exact version.\n            for (SkillDetail detail : metadataDao.listVersions(name)) {\n                if (detail.getChecksum() != null && detail.getChecksum().startsWith(version)) {\n                    return detail.getVersion();\n                }\n            }\n            return version;\n        }\n        return metadataDao\n                .latestVersion(name)\n                .orElseThrow(() -> new IllegalArgumentException(\"Skill not found: \" + name));\n    }\n\n    private Map<String, Object> parseManifest(String manifestJson) {\n        if (manifestJson == null || manifestJson.isBlank()) {\n            throw new IllegalArgumentException(\"Skill manifest is required\");\n        }\n        try {\n            return MAPPER.readValue(manifestJson, MAP_TYPE);\n        } catch (IOException e) {\n            throw new IllegalArgumentException(\"Invalid skill manifest JSON: \" + e.getMessage(), e);\n        }\n    }\n\n    private byte[] readPackage(MultipartFile packageFile) {\n        try {\n            byte[] bytes = packageFile.getBytes();\n            if (bytes.length > maxPackageBytes) {\n                throw new IllegalArgumentException(\n                        \"Skill package exceeds max size of \" + maxPackageBytes + \" bytes\");\n            }\n            return bytes;\n        } catch (IOException e) {\n            throw new IllegalArgumentException(","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java#L384-L420","documentation":"Thrown by register() (via parseManifest) when the manifestJson argument is null or blank. The manifest is the @RequestPart(\"manifest\") of the register multipart request and must be a non-empty JSON document. Without it there is no metadata to validate or version against.","triggerScenarios":"POST /api/skills/register with the 'manifest' part missing, empty, or containing only whitespace. Spring binds a missing required @RequestPart to a 400 before this in some configs, but a present-but-blank part reaches here.","commonSituations":"Client sends the 'package' part but forgets the 'manifest' part; a manifest field that is an empty string in a form builder; content-type negotiation causing the manifest part to deserialize as blank.","solutions":["Include a non-empty JSON manifest part in the multipart request.","At minimum send {} if you want SKILL.md frontmatter to drive all fields — but the version will fall back to a checksum prefix.","Verify the multipart form has both 'manifest' (text) and 'package' (file) parts."],"exampleFix":"# before: only the package part sent\ncurl -F 'package=@skill.zip' /api/skills/register\n# after: include a manifest part\ncurl -F 'manifest={\"name\":\"foo\",\"version\":\"1.0.0\"}' -F 'package=@skill.zip' /api/skills/register","handlingStrategy":"validation","validationCode":"// Client-side: ensure manifest part is present and non-blank\nif (manifest == null || manifest.isBlank()) {\n    throw new IllegalArgumentException(\"manifest part is required\");\n}","typeGuard":"static boolean manifestPresent(String m) { return m != null && !m.isBlank(); }","tryCatchPattern":null,"preventionTips":["Always send both 'manifest' and 'package' parts in the multipart form.","Default the manifest to '{}' if you want SKILL.md to drive all fields."],"tags":["java","conductor","skill-registry","validation","multipart-upload"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}