{"record":{"id":"295c283e8775c6ee","repo":"siyuan-note/siyuan","slug":"ids-is-required","errorCode":null,"errorMessage":"--ids is required","messagePattern":"--ids is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/cli/cmd/attr.go","lineNumber":118,"sourceCode":"\t\t\treturn nil\n\t\t}\n\n\t\tif err := model.SetBlockAttrs(id, nameValues); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tmodel.AppendPushReloadFiletreeEntry()\n\t\tfmt.Println(\"ok\")\n\t\treturn nil\n\t},\n}\n\nvar attrBatchGetCmd = &cobra.Command{\n\tUse:   \"batch-get --ids id1,id2,...\",\n\tShort: \"Batch get block attributes\",\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tidsStr, _ := cmd.Flags().GetString(\"ids\")\n\t\tif idsStr == \"\" {\n\t\t\treturn fmt.Errorf(\"--ids is required\")\n\t\t}\n\n\t\tids := strings.Split(idsStr, \",\")\n\t\tfor i := range ids {\n\t\t\tids[i] = strings.TrimSpace(ids[i])\n\t\t}\n\n\t\tattrs := sql.BatchGetBlockAttrs(ids)\n\t\tswitch outputFormat {\n\t\tcase \"json\":\n\t\t\tdata, _ := json.MarshalIndent(attrs, \"\", \"  \")\n\t\t\tfmt.Println(string(data))\n\t\tdefault:\n\t\t\tfor id, a := range attrs {\n\t\t\t\tfmt.Printf(\"\\n[%s]\\n\", id)\n\t\t\t\tprintAttrTable(a)\n\t\t\t}\n\t\t}","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/cli/cmd/attr.go#L100-L136","documentation":"Thrown by the `attr batch-get` subcommand when `--ids` is empty. `--ids` is a single comma-separated string (not a StringArray) that gets split into a slice; an empty string means nothing to look up. The call into `sql.BatchGetBlockAttrs(ids)` is skipped.","triggerScenarios":"Running `siyuan-kernel attr batch-get` with no `--ids`, or `--ids \"\"`. Only an empty string triggers it — whitespace-only values pass through and are trimmed per-element.","commonSituations":"Forgetting the flag; passing the IDs as positional args instead of via `--ids`; expecting `--ids` to be repeatable like `--attr` (it is not — it is one comma-joined string).","solutions":["Supply a comma-separated list: `siyuan-kernel attr batch-get --ids 20260605100657-v080a4j,20260605100658-abc1234`","Remember `--ids` is a single string, not repeated like `--attr`","Trim stray whitespace; each element is `strings.TrimSpace`-d but the whole string must be non-empty"],"exampleFix":"// before\nsiyuan-kernel attr batch-get\n// after\nsiyuan-kernel attr batch-get --ids 20260605100657-v080a4j,20260605100658-abc1234","handlingStrategy":"validation","validationCode":"// Build the comma-joined ids string defensively.\nids := []string{\"20260605100657-v080a4j\", \"20260605100658-abc1234\"}\ncleaned := []string{}\nfor _, id := range ids {\n    if t := strings.TrimSpace(id); t != \"\" {\n        cleaned = append(cleaned, t)\n    }\n}\nif len(cleaned) == 0 {\n    return fmt.Errorf(\"no block IDs to query\")\n}\nidsStr := strings.Join(cleaned, \",\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember `--ids` is ONE comma-joined string, not a repeatable flag","Trim and drop empty elements before joining to avoid stray commas","Pre-validate IDs against the blocktree via `sql` if hard failures are costly"],"tags":["cli","attr","argument-validation","go"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}