siyuan-note/siyuan · error

skill not found

Error message

skill not found: %s

What it means

LoadSkill resolves a skill locator of the form 'name' or 'name/relative/path' against the discovered skill records (enabled user skills plus built-ins). When no record matches the requested skill name, it returns 'skill not found: %s'.

Solutions

  1. List available skills (discover/skill list) and copy the exact name
  2. Enable the skill in the AI settings so it appears in enabledUserSkills
  3. Verify the skill directory exists in the user skills folder or as a bundled skill
  4. Retry LoadSkill with the corrected locator, including 'name/resource' form for resources

Example fix

// before
res, err := util.LoadSkill("code-review", enabled) // skill not found: code-review
// after
discovered := util.DiscoverSkills(enabled)
// discovered shows name "code-reviewer"
res, err := util.LoadSkill("code-reviewer", enabled)
Defensive patterns

Strategy: validation

Validate before calling

func hasSkill(name string, enabled []string) bool {
  for _, rec := range util.DiscoverSkills(enabled) {
    if rec.Name == name { return true }
  }
  return false
}
// call util.LoadSkill only if hasSkill(name, enabled)

Try / catch

res, err := util.LoadSkill(locator, enabled)
if err != nil && strings.HasPrefix(err.Error(), "skill not found") {
  return fmt.Errorf("unknown skill %q — list available skills first", locator)
}

Prevention

When it happens

Trigger: Calling LoadSkill (or the skillLoad API) with a skill name that is not among discovered records — disabled user skills, misspelled names, or skills absent from both workspace and user skill directories.

Common situations: Typo in the skill name; skill exists but is disabled (not in enabledUserSkills); skill deleted or not installed in the expected skills directory; case mismatch in the name.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/027d4d50d0d4d713. Report an issue: GitHub.

Appendix: source

Thrown at kernel/util/skill.go:245

func findSkillRecord(records []skillRecord, name string) (skillRecord, bool) {
	key := skillKey(name)
	for _, record := range records {
		for _, alias := range skillAliases(record) {
			if alias == key {
				return record, true
			}
		}
	}
	return skillRecord{}, false
}

// LoadSkill 按技能名加载正文,或按“技能名/相对路径”加载单个文本资源。
func LoadSkill(locator string, enabledUserSkills []string) (*SkillLoadResult, error) {
	name, resource := splitSkillLocator(locator)
	record, ok := findSkillRecord(resolveSkillRecords(enabledUserSkills), name)
	if !ok {
		return nil, fmt.Errorf("skill not found: %s", name)
	}

	skillDir := filepath.Join(record.Root, record.DirName)
	result := &SkillLoadResult{
		Name:     name,
		Content:  record.Body,
		SkillDir: skillDir,
	}
	if resource == "" {
		result.Resources, result.ResourcesTruncated = listSkillResources(skillDir)
		return result, nil
	}

	resource, err := normalizeSkillResourcePath(resource)
	if err != nil {
		return nil, err
	}
	if resource == "SKILL.md" {

View on GitHub (pinned to 9f775e8a12)