{"record":{"id":"b653af7c4dc3bb50","repo":"conductor-oss/conductor","slug":"skillref-is-required","errorCode":null,"errorMessage":"skillRef is required","messagePattern":"skillRef 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":307,"sourceCode":"                        .path(cleanPath)\n                        .contentType(contentType(cleanPath))\n                        .size(data.length)\n                        .binary(binary)\n                        .content(binary ? null : new String(data, StandardCharsets.UTF_8))\n                        .contentBase64(binary ? Base64.getEncoder().encodeToString(data) : null)\n                        .build();\n            }\n            throw new IllegalArgumentException(\"Skill file not found: \" + cleanPath);\n        } catch (IOException e) {\n            throw new IllegalStateException(\"Failed to read skill file: \" + e.getMessage(), e);\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public Map<String, Object> resolveRawConfig(Map<String, Object> skillRef) {\n        requireSkillStorage();\n        if (skillRef == null) {\n            throw new IllegalArgumentException(\"skillRef is required\");\n        }\n        String name = requiredString(skillRef, \"name\");\n        String version = stringValue(skillRef.get(\"version\"));\n        SkillDetail detail = get(name, version);\n        Map<String, Object> rawConfig = rawConfigForDetail(detail, new HashSet<>());\n        Object model = skillRef.get(\"model\");\n        if (model instanceof String s && !s.isBlank()) {\n            rawConfig.put(\"model\", s);\n        }\n        Object agentModels = skillRef.get(\"agentModels\");\n        if (agentModels instanceof Map<?, ?> map && !map.isEmpty()) {\n            rawConfig.put(\"agentModels\", MAPPER.convertValue(map, Map.class));\n        }\n        Object workspace = skillRef.get(\"workspace\");\n        if (workspace instanceof Map<?, ?> map && !map.isEmpty()) {\n            rawConfig.put(\"workspace\", MAPPER.convertValue(map, Map.class));\n        }\n        Object params = skillRef.get(\"params\");","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java#L289-L325","documentation":"Thrown by resolveRawConfig() when the skillRef argument is null. resolveRawConfig is called internally by AgentService (line 1222) when starting an agent from a skillRef, and requires a non-null map containing at least a 'name' key. A null skillRef means no skill was referenced at all.","triggerScenarios":"AgentStartRequest submitted with framework=skill but skillRef=null (or omitted), routed to AgentService which calls resolveRawConfig(null). Also a direct service caller passing null.","commonSituations":"Client builds an agent start request and forgets to populate skillRef; a workflow definition references a skill but the skillRef field is left empty due to a templating error; JSON deserialization yielding null when the field is absent and not defaulted.","solutions":["Populate skillRef with at least {\"name\":\"<skill-name>\"} in the AgentStartRequest.","Add a null/empty check on skillRef on the client before starting the agent.","If starting without a skill is valid, use a different framework and do not call the skill path."],"exampleFix":"// before\nAgentStartRequest.builder().framework(\"skill\").skillRef(null).build();\n// after\nAgentStartRequest.builder()\n    .framework(\"skill\")\n    .skillRef(Map.of(\"name\",\"foo\",\"version\",\"1.0.0\"))\n    .build();","handlingStrategy":"validation","validationCode":"// Before starting an agent from a skill, assert skillRef is present and named\nif (request.getSkillRef() == null || !(request.getSkillRef().get(\"name\") instanceof String s && !s.isBlank())) {\n    throw new IllegalArgumentException(\"skillRef.name is required for framework=skill\");\n}","typeGuard":"static boolean hasValidSkillRef(AgentStartRequest r) {\n    Map<String,Object> ref = r.getSkillRef();\n    return ref != null && ref.get(\"name\") instanceof String s && !s.isBlank();\n}","tryCatchPattern":null,"preventionTips":["On the client, require skillRef.name whenever framework=skill is selected.","Add a request-level validator for AgentStartRequest that fails fast on a null skillRef."],"tags":["java","conductor","skill-registry","validation","agent"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}