{"record":{"id":"9474621deee44a36","repo":"siyuan-note/siyuan","slug":"unsupported-skill-operation","errorCode":null,"errorMessage":"unsupported skill operation","messagePattern":"unsupported skill operation","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/skill_manage.go","lineNumber":298,"sourceCode":"\t\tif revision == \"\" || revision != currentRevision {\n\t\t\treturn errors.New(\"skill changed; reload it before saving, renaming or deleting\")\n\t\t}\n\t\tif err = root.Rename(target, p); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tcomplete = true\n\treturn nil\n}\n\nfunc ManageSkillFiles(request SkillFileRequest) (SkillFileData, error) {\n\tskillManagementLock.Lock()\n\tdefer skillManagementLock.Unlock()\n\tret := SkillFileData{}\n\tswitch request.Action {\n\tcase \"list\", \"read\", \"write\", \"create\", \"mkdir\", \"move\", \"remove\":\n\tdefault:\n\t\treturn ret, errors.New(\"unsupported skill operation\")\n\t}\n\troot, err := openManagedSkillsRoot()\n\tif err != nil {\n\t\treturn ret, err\n\t}\n\tdefer root.Close()\n\tif request.Action == \"list\" {\n\t\tret.Entries = []SkillFileEntry{}\n\t\terr = fs.WalkDir(root.FS(), \".\", func(p string, entry fs.DirEntry, walkErr error) error {\n\t\t\tif walkErr != nil || p == \".\" {\n\t\t\t\treturn walkErr\n\t\t\t}\n\t\t\t// 未解析或被同名技能遮蔽的目录也保留在列表中，链接只展示而不跟随。\n\t\t\teditable := false\n\t\t\tif entry.Type().IsRegular() && strings.Contains(p, \"/\") && validateManagedSkillPath(p) == nil {\n\t\t\t\tif err := checkManagedSkillPath(root, p); err == nil {\n\t\t\t\t\t_, err = readManagedSkillSource(root, p)\n\t\t\t\t\teditable = err == nil","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/skill_manage.go#L280-L316","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use exactly one of: \"list\", \"read\", \"write\", \"create\", \"mkdir\", \"move\", \"remove\"","Map \"delete\" to \"remove\" and \"rename\" to \"move\"","Check the request casing (verbs are lowercase)"],"exampleFix":"// before\nManageSkillFiles(SkillFileRequest{Action: \"delete\", Path: \"my-skill\"})\n// after\nManageSkillFiles(SkillFileRequest{Action: \"remove\", Path: \"my-skill\", Revision: rev})","handlingStrategy":"validation","validationCode":"var validSkillActions = map[string]bool{\"list\":true,\"read\":true,\"write\":true,\"create\":true,\"mkdir\":true,\"move\":true,\"remove\":true}\nif !validSkillActions[req.Action] { return fmt.Errorf(\"unsupported action %q\", req.Action) }","typeGuard":"func isSkillAction(a string) bool {\n  switch a { case \"list\",\"read\",\"write\",\"create\",\"mkdir\",\"move\",\"remove\": return true }\n  return false\n}","tryCatchPattern":"if err := ManageSkillFiles(req); err != nil && strings.Contains(err.Error(), \"unsupported skill operation\") {\n  // log req.Action and map it to a supported verb\n}","preventionTips":["Use the exact lowercase verbs list/read/write/create/mkdir/move/remove","Map delete->remove and rename->move in client adapters","Keep request builders in one module so verb names stay centralized"],"tags":["api","invalid-argument","skills"],"backgroundTag":"invalid-enum-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}