{"record":{"id":"7ab68ba248594638","repo":"conductor-oss/conductor","slug":"missing-required-field-key","errorCode":null,"errorMessage":"Missing required field: {key}","messagePattern":"Missing required field: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java","lineNumber":968,"sourceCode":"            MessageDigest digest = MessageDigest.getInstance(\"SHA-256\");\n            return hex(digest.digest(bytes));\n        } catch (Exception e) {\n            throw new IllegalStateException(\"SHA-256 digest is unavailable\", e);\n        }\n    }\n\n    private static String hex(byte[] bytes) {\n        StringBuilder sb = new StringBuilder(bytes.length * 2);\n        for (byte b : bytes) {\n            sb.append(String.format(\"%02x\", b));\n        }\n        return sb.toString();\n    }\n\n    private static String requiredString(Map<String, Object> map, String key) {\n        String value = stringValue(map.get(key));\n        if (value == null || value.isBlank()) {\n            throw new IllegalArgumentException(\"Missing required field: \" + key);\n        }\n        return value;\n    }\n\n    private static String stringValue(Object value) {\n        return value instanceof String s ? s : null;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private static Map<String, Object> toMap(Object value) {\n        if (value instanceof Map<?, ?> map) {\n            return MAPPER.convertValue(map, Map.class);\n        }\n        return Map.of();\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private static Map<String, Object> deepCopy(Map<String, Object> value) {","sourceCodeStart":950,"sourceCodeEnd":986,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java#L950-L986","documentation":"requiredString throws when a mandatory metadata field is absent, null, or whitespace-only in a skill manifest. It is the generic guard for fields the registry cannot do without (e.g. name, version, the package's main entry). The key name in the message identifies which field is missing.","triggerScenarios":"A manifest omits a required key, sets it to `null`, or supplies only whitespace (e.g. `description: \"   \"`). requiredString returns null and throws, naming the key.","commonSituations":"Author deleted a field thinking it was optional; a generator template was not filled in; copy-paste left a placeholder value blank.","solutions":["Look at the `{key}` in the message — add a non-blank value for that exact field.","Consult the skill manifest schema/spec to confirm which fields are mandatory.","Re-validate the manifest locally (yaml lint + presence check) before uploading."],"exampleFix":"// before\nname: my-skill\nversion:    # empty\n// after\nname: my-skill\nversion: \"1.0.0\"","handlingStrategy":"validation","validationCode":"void requireFields(Map<String,Object> manifest, String... keys) {\n    for (String k : keys) {\n        Object v = manifest.get(k);\n        if (!(v instanceof String s) || s.isBlank())\n            throw new IllegalArgumentException(\"Missing required field: \" + k);\n    }\n}","typeGuard":"boolean hasRequiredFields(Map<String,Object> m, String... keys) {\n    for (String k : keys) { Object v = m.get(k); if (!(v instanceof String s) || s.isBlank()) return false; }\n    return true;\n}","tryCatchPattern":"try { skillRegistry.publish(manifest); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Missing required field\")) return badRequest(e.getMessage());\n    throw e;\n}","preventionTips":["Maintain a checklist of mandatory manifest fields and lint it.","Use a schema-validated manifest tool.","Fill template placeholders before upload."],"tags":["skill-registry","metadata","required-field","validation"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}