{"record":{"id":"9efbcd8c84d643bb","repo":"siyuan-note/siyuan","slug":"field-groups-must-not-be-empty","errorCode":null,"errorMessage":"Field [groups] must not be empty","messagePattern":"Field \\[groups\\] must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/clipboard_input.go","lineNumber":63,"sourceCode":"\t\tfields, err := blockRequestFields(reader, \"/api/clipboard/cleanupRichText\")\n\t\tif err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\trequest.Batch, err = legacyField[string](fields, \"batch\", \"String\", true)\n\t\tif err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\trequest.Batch = strings.TrimSpace(request.Batch)\n\t\tif request.Batch == \"\" {\n\t\t\treturn request, fmt.Errorf(\"Field [batch] must not be empty\")\n\t\t}\n\t\tgroups, err := legacyField[[]json.RawMessage](fields, \"groups\", \"Array\", true)\n\t\tif err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\trequest.Groups = make([]string, 0, len(groups))\n\t\tif len(groups) == 0 {\n\t\t\treturn request, fmt.Errorf(\"Field [groups] must not be empty\")\n\t\t}\n\t\tfor i, raw := range groups {\n\t\t\tvar group string\n\t\t\tif bytes.Equal(raw, []byte(\"null\")) || json.Unmarshal(raw, &group) != nil {\n\t\t\t\treturn request, fmt.Errorf(\"Field [groups.%d] should be of type [String]\", i)\n\t\t\t}\n\t\t\trequest.Groups = append(request.Groups, group)\n\t\t}\n\t\treturn\n\t}\n}\n","sourceCodeStart":45,"sourceCodeEnd":75,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/clipboard_input.go#L45-L75","documentation":"The groups array in /api/clipboard/cleanupRichText must contain at least one element. The groups identify which block groups to clean up; an empty array is rejected because the call would otherwise be a no-op.","triggerScenarios":"POSTing {\"batch\":\"...\",\"groups\":[]} to /api/clipboard/cleanupRichText, or a groups-building loop that collects nothing (e.g. no blocks matched the filter).","commonSituations":"Cleaning up after a copy where no groups were actually registered; filtering removed all group IDs before the call; assuming groups is optional and sending an empty array.","solutions":["Include at least one group identifier string in the groups array","Skip the cleanup call entirely (client-side) when there are no groups to clean","Verify the group-collection logic upstream so groups is populated before the request"],"exampleFix":"// before\nfetchPost(\"/api/clipboard/cleanupRichText\", {batch, groups: []})\n// after\nif (groups.length > 0) { fetchPost(\"/api/clipboard/cleanupRichText\", {batch, groups}) }","handlingStrategy":"validation","validationCode":"if (!Array.isArray(groups) || groups.length === 0) throw new Error('groups must be a non-empty array');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Skip cleanup calls when no groups were registered","Check group-collection filters that can produce empty arrays","Treat empty groups as a no-op, not a request"],"tags":["validation","clipboard","request-body"],"backgroundTag":"empty-required-field","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"}