siyuan-note/siyuan · error

unsupported skill operation

Error message

unsupported skill operation

What it means

ManageSkillFiles dispatches on request.Action and only accepts the fixed verbs list/read/write/create/mkdir/move/remove. Any other action string is rejected with this error before the storage root is even opened. It is a typo/contract guard for the skill management API surface.

Solutions

  1. Use exactly one of: "list", "read", "write", "create", "mkdir", "move", "remove"
  2. Map "delete" to "remove" and "rename" to "move"
  3. Check the request casing (verbs are lowercase)

Example fix

// before
ManageSkillFiles(SkillFileRequest{Action: "delete", Path: "my-skill"})
// after
ManageSkillFiles(SkillFileRequest{Action: "remove", Path: "my-skill", Revision: rev})
Defensive patterns

Strategy: validation

Validate before calling

var validSkillActions = map[string]bool{"list":true,"read":true,"write":true,"create":true,"mkdir":true,"move":true,"remove":true}
if !validSkillActions[req.Action] { return fmt.Errorf("unsupported action %q", req.Action) }

Type guard

func isSkillAction(a string) bool {
  switch a { case "list","read","write","create","mkdir","move","remove": return true }
  return false
}

Try / catch

if err := ManageSkillFiles(req); err != nil && strings.Contains(err.Error(), "unsupported skill operation") {
  // log req.Action and map it to a supported verb
}

Prevention

When it happens

Trigger: Calling ManageSkillFiles (or the manageSkillsContract HTTP endpoint) with an Action value other than the seven supported ones — e.g. "delete", "rename", "touch", "listAll", or a capitalized/misspelled verb.

Common situations: Translating code from another file API that uses "delete"/"rename" instead of "remove"/"move"; typos or case mismatches when hand-writing API requests; plugin code written against an older draft of the API.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at kernel/util/skill_manage.go:298

		if revision == "" || revision != currentRevision {
			return errors.New("skill changed; reload it before saving, renaming or deleting")
		}
		if err = root.Rename(target, p); err != nil {
			return err
		}
	}
	complete = true
	return nil
}

func ManageSkillFiles(request SkillFileRequest) (SkillFileData, error) {
	skillManagementLock.Lock()
	defer skillManagementLock.Unlock()
	ret := SkillFileData{}
	switch request.Action {
	case "list", "read", "write", "create", "mkdir", "move", "remove":
	default:
		return ret, errors.New("unsupported skill operation")
	}
	root, err := openManagedSkillsRoot()
	if err != nil {
		return ret, err
	}
	defer root.Close()
	if request.Action == "list" {
		ret.Entries = []SkillFileEntry{}
		err = fs.WalkDir(root.FS(), ".", func(p string, entry fs.DirEntry, walkErr error) error {
			if walkErr != nil || p == "." {
				return walkErr
			}
			// 未解析或被同名技能遮蔽的目录也保留在列表中,链接只展示而不跟随。
			editable := false
			if entry.Type().IsRegular() && strings.Contains(p, "/") && validateManagedSkillPath(p) == nil {
				if err := checkManagedSkillPath(root, p); err == nil {
					_, err = readManagedSkillSource(root, p)
					editable = err == nil

View on GitHub (pinned to 9f775e8a12)