{"record":{"id":"bb71b8c6952f9c0d","repo":"zylon-ai/private-gpt","slug":"skill-management-tools-require-a-skillartifact-in","errorCode":null,"errorMessage":"Skill management tools require a SkillArtifact in the tool context.","messagePattern":"Skill management tools require a SkillArtifact in the tool context\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/tools/processors/skill_management_processor.py","lineNumber":108,"sourceCode":"                built_any |= _replace_tool(\n                    request,\n                    tool,\n                    [\n                        builder.build_list_skills(\n                            name=tool.name or SKILL_LIST_TOOL_NAME,\n                            type=tool.type or SKILL_LIST_TOOL_NAME + \"_v1\",\n                        )\n                    ],\n                )\n        return built_any\n\n    def _make_builder(\n        self, request: ResolvedChatRequest, tool: Any\n    ) -> SkillManagementToolBuilder:\n        tool_context = _get_tool_context(request, tool)\n        skill_artifacts = [a for a in tool_context if isinstance(a, SkillArtifact)]\n        if not skill_artifacts:\n            raise ValueError(\n                \"Skill management tools require a SkillArtifact in the tool context.\"\n            )\n        if len(skill_artifacts) > 1:\n            raise ValueError(\n                \"Only one SkillArtifact is supported per skill management tool.\"\n            )\n        return SkillManagementToolBuilder(\n            skill_service=self._skill_service,\n            skill_filter=skill_artifacts[0].skill_filter,\n            skill_injection_mode=self._settings.skills.skill_injection_mode,\n        )\n","sourceCodeStart":90,"sourceCodeEnd":120,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/tools/processors/skill_management_processor.py#L90-L120","documentation":"Raised by the SkillManagementProcessor's _make_builder when a skill management tool (e.g. skill list) is being resolved but its tool context contains no SkillArtifact. The builder needs the artifact's skill_filter to construct SkillManagementToolBuilder, so the request fails.","triggerScenarios":"Including a skill management tool (SKILL_LIST_TOOL_NAME or siblings) in tool_config.tools while its tool_context is empty or holds only non-skill artifacts.","commonSituations":"Enabling skill tools globally without scoping them to a skill set; attaching the SkillArtifact to another tool entry in a multi-tool request; skills subsystem disabled but the tool still requested.","solutions":["Attach exactly one SkillArtifact (with skill_filter) to the skill management tool's context","Or remove skill management tools from the request when no skill scope applies","Check the skills settings (settings.skills) are configured and the skill service is available"],"exampleFix":"# before\ntools=[ToolConfig(name=SKILL_LIST_TOOL_NAME)]\n# after\ntools=[\n    ToolConfig(\n        name=SKILL_LIST_TOOL_NAME,\n        context=[SkillArtifact(skill_filter=SkillFilter(...))],\n    )\n]","handlingStrategy":"validation","validationCode":"skills = [a for a in (tool_context or []) if isinstance(a, SkillArtifact)]\nif not skills:\n    # remove skill management tools from the request or attach a SkillArtifact","typeGuard":"def is_skill_artifact(ctx: object) -> bool:\n    return isinstance(ctx, SkillArtifact)","tryCatchPattern":"try:\n    resp = await client.chat(request)\nexcept ValueError as e:\n    if \"require a SkillArtifact\" in str(e):\n        # attach SkillArtifact(skill_filter=...) and resend\n        raise","preventionTips":["Only expose skill management tools when a skill scope has been chosen","Validate tool/artifact pairings client-side with a shared schema","Test skill tool requests in CI with a minimal SkillArtifact fixture"],"tags":["tools","validation","skills","request-validation"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}