{"record":{"id":"30ba2d8fac023b54","repo":"siyuan-note/siyuan","slug":"field-assets-d-box-should-be-of-type-string","errorCode":null,"errorMessage":"Field [assets.%d.box] should be of type [String]","messagePattern":"Field \\[assets\\.(.+?)\\.box\\] should be of type \\[String\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/clipboard_input.go","lineNumber":37,"sourceCode":"\t\t\treturn request, err\n\t\t}\n\t\tif len(assets) == 0 {\n\t\t\treturn request, fmt.Errorf(\"Field [assets] must not be empty\")\n\t\t}\n\t\trequest.Assets = make([]RichClipboardAsset, 0, len(assets))\n\t\tfor i, raw := range assets {\n\t\t\tvar asset map[string]json.RawMessage\n\t\t\tif json.Unmarshal(raw, &asset) != nil || asset == nil {\n\t\t\t\treturn request, fmt.Errorf(\"Field [assets.%d] should be of type [Object]\", i)\n\t\t\t}\n\t\t\tvar index float64\n\t\t\tvar path, box string\n\t\t\tif bytes.Equal(asset[\"index\"], []byte(\"null\")) || json.Unmarshal(asset[\"index\"], &index) != nil || index < 0 || index != float64(int(index)) || json.Unmarshal(asset[\"path\"], &path) != nil || strings.TrimSpace(path) == \"\" {\n\t\t\t\treturn request, fmt.Errorf(\"Invalid rich clipboard asset at index [%d]\", i)\n\t\t\t}\n\t\t\tif value, exists := asset[\"box\"]; exists {\n\t\t\t\tif bytes.Equal(value, []byte(\"null\")) || json.Unmarshal(value, &box) != nil {\n\t\t\t\t\treturn request, fmt.Errorf(\"Field [assets.%d.box] should be of type [String]\", i)\n\t\t\t\t}\n\t\t\t}\n\t\t\trequest.Assets = append(request.Assets, RichClipboardAsset{Index: int(index), Path: strings.TrimSpace(path), Box: strings.TrimSpace(box)})\n\t\t}\n\t\treturn\n\t}\n\tCleanupRichText.decodeRequest = func(reader io.Reader) (request CleanupRichTextRequest, err error) {\n\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\")","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/clipboard_input.go#L19-L55","documentation":"The optional box field of a rich clipboard asset must be a JSON string when present. Sending null or a non-string value (number, boolean, object, array) is rejected; the field must simply be omitted if not needed.","triggerScenarios":"Sending {\"index\":0,\"path\":\"/a.png\",\"box\":null} or box: 123 / box: {\"id\":\"x\"} in an asset of the /api/clipboard/prepareRichText payload.","commonSituations":"A client framework serializes undefined/absent notebook IDs as null instead of omitting the key; typed bindings pass a number where a notebook box ID string is expected; copy-pasting payload templates with placeholder null values.","solutions":["Omit the box key entirely when there is no notebook box to specify","Ensure box is a string notebook ID (e.g. \"20210808180117-czj9hvh\") when present","Strip null-valued optional fields before sending the request"],"exampleFix":"// before\n{index: 0, path: \"/assets/a.png\", box: null}\n// after\n{index: 0, path: \"/assets/a.png\"}","handlingStrategy":"validation","validationCode":"if ('box' in asset && (asset.box === null || typeof asset.box !== 'string')) delete asset.box;","typeGuard":"const hasValidBox = (a) => !('box' in a) || (typeof a.box === 'string' && a.box !== null);","tryCatchPattern":null,"preventionTips":["Omit optional keys instead of setting them to null","Configure serializers to drop undefined/null optional fields","Only pass real notebook box ID strings"],"tags":["validation","type-mismatch","clipboard"],"backgroundTag":"type-mismatch","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"}