{"record":{"id":"f6fb67e2c15cb001","repo":"siyuan-note/siyuan","slug":"keyword-is-required","errorCode":null,"errorMessage":"keyword is required","messagePattern":"keyword is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/cli/cmd/document.go","lineNumber":374,"sourceCode":"\t\tif \"/\" == targetHPath {\n\t\t\treturn \"/\", nil\n\t\t}\n\t}\n\n\tif targetPath, found := lookup(targetHPath); found {\n\t\treturn targetPath, nil\n\t}\n\treturn \"\", fmt.Errorf(\"target human-readable path not found: %s\", targetHPath)\n}\n\nvar documentSearchCmd = &cobra.Command{\n\tUse:   \"search <keyword>\",\n\tShort: \"Search documents by keyword\",\n\tArgs:  cobra.MinimumNArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tkeyword := args[0]\n\t\tif keyword == \"\" {\n\t\t\treturn fmt.Errorf(\"keyword is required\")\n\t\t}\n\t\tdocs := model.SearchDocs(keyword, false, nil)\n\t\tswitch outputFormat {\n\t\tcase \"json\":\n\t\t\tdata, _ := json.MarshalIndent(docs, \"\", \"  \")\n\t\t\tfmt.Println(string(data))\n\t\tdefault:\n\t\t\tif len(docs) == 0 {\n\t\t\t\tfmt.Println(\"No documents found.\")\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tw := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)\n\t\t\tfmt.Fprintln(w, \"TYPE\\tID\\tNAME\\tHPATH\")\n\t\t\tfor _, d := range docs {\n\t\t\t\ttyp, id, name := documentSearchDisplayFields(d)\n\t\t\t\tfmt.Fprintf(w, \"%s\\t%s\\t%s\\t%s\\n\", typ, id, name, d[\"hPath\"])\n\t\t\t}\n\t\t\tw.Flush()","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/cli/cmd/document.go#L356-L392","documentation":"The `siyuan document search` command takes the keyword as its first positional argument (Args: cobra.MinimumNArgs(1)). This guard fires when args[0] exists but is an empty string, meaning search was called with a quoted empty argument. Without any argument cobra itself rejects the call; with \"\" the command returns this error before calling model.SearchDocs.","triggerScenarios":"Running `document search \"\"`; scripts interpolating an empty variable: `document search \"$Q\"` with Q unset; pipeline stages that pass an empty first field after word splitting.","commonSituations":"Search terms read from a config or prompt that defaulted to empty; loops over keywords where one entry is blank; forgotten argument that shell quoting turned into an empty string rather than a missing one.","solutions":["Provide a non-empty keyword: `siyuan document search <keyword>`","Fail fast in the calling script when the search term variable is empty","Filter blank entries out of keyword lists before looping over the command"],"exampleFix":"// before\ndocument search \"$QUERY\"   # QUERY may be empty\n// after\n: \"${QUERY:?QUERY must not be empty}\"\ndocument search \"$QUERY\"","handlingStrategy":"validation","validationCode":"if [ -z \"${QUERY:-}\" ]; then echo \"keyword is required\" >&2; exit 2; fi\nsiyuan document search \"$QUERY\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call search with an empty quoted argument; check the term variable first","Filter empty strings out of keyword arrays before iterating","Require search terms via ${VAR:?} expansion or explicit prompts"],"tags":["cli","validation","empty-argument"],"backgroundTag":"missing-required-argument","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"}