flipped-aurora/gin-vue-admin · error
工具类型不支持
Error message
工具类型不支持
What it means
toolSkillsDir maps a tool key to its config directory via skillToolDirs (copilot, claude, cursor, trae, codex). Any other value returns "工具类型不支持". It is the entry gate for almost every skill operation, so a bad tool key fails List/Tools/Get/Download/SkillDir calls.
Source
Thrown at server/service/system/sys_skills.go:521
rc.Close()
return err
}
_, err = io.Copy(out, rc)
rc.Close()
out.Close()
if err != nil {
return err
}
}
return nil
}
func (s *SkillsService) toolSkillsDir(tool string) (string, error) {
toolDir, ok := skillToolDirs[tool]
if !ok {
return "", errors.New("工具类型不支持")
}
root := strings.TrimSpace(global.GVA_CONFIG.AutoCode.Root)
if root == "" {
root = "."
}
skillsDir := filepath.Join(root, toolDir, "skills")
if err := os.MkdirAll(skillsDir, os.ModePerm); err != nil {
return "", err
}
return skillsDir, nil
}
func (s *SkillsService) skillDir(tool, skill string) (string, error) {
skillsDir, err := s.toolSkillsDir(tool)
if err != nil {
return "", err
}
return filepath.Join(skillsDir, skill), nilView on GitHub (pinned to 3136500ef3)
Solutions
- Send the exact lowercase key: copilot, claude, cursor, trae, or codex
- Add the new tool to skillToolDirs (and skillToolOrder/skillToolLabels) in sys_skills.go if support is genuinely missing
- Normalize/trim and lowercase the tool value before calling the service
Example fix
// before List(ctx, "VSCode") // after List(ctx, "claude") // exact key from skillToolDirs
Defensive patterns
Strategy: validation
Validate before calling
var validTools = map[string]bool{"copilot": true, "claude": true, "cursor": true, "trae": true, "codex": true}
if !validTools[tool] { return fmt.Errorf("不支持的工具类型: %q", tool) } Type guard
func isKnownTool(t string) bool {
switch t { case "copilot", "claude", "cursor", "trae", "codex": return true }
return false
} Try / catch
if err := svc.List(ctx, tool); err != nil {
if err.Error() == "工具类型不支持" {
return fmt.Errorf("工具必须是小写 key 之一 copilot/claude/cursor/trae/codex: %w", err)
}
return err
} Prevention
- Always send the lowercase key, never the display label
- Derive tool values from the Tools() API rather than hardcoding
- When adding a new tool, update skillToolDirs/skillToolOrder/skillToolLabels together
When it happens
Trigger: Calling any skills API (Tools, List, GetGlobalConstraint, DownloadOnlineSkill, Save, CreateScript, ...) with tool not exactly one of "copilot","claude","cursor","trae","codex" — e.g. "vscode", "Claude" (case mismatch), or empty.
Common situations: Frontend sending a display label ("Claude") instead of the key; new tool added to the frontend but not to skillToolDirs; typo or different casing; client caching an old tool list.
Related errors
- packageType 必须是 'package' 或 'plugin'
- packageInfo.template 必须是 'package' 或 'plugin'
- 脚本类型不支持
- 参数错误:executionPlan 必须提供
- packageName 不能为空
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/86f6563fc7ea40d9.
Report an issue: GitHub.