siyuan-note/siyuan · error
Field [assets. .box] should be of type [String]
Error message
Field [assets.%d.box] should be of type [String]
What it means
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.
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
Example fix
// before
{index: 0, path: "/assets/a.png", box: null}
// after
{index: 0, path: "/assets/a.png"} Defensive patterns
Strategy: validation
Validate before calling
if ('box' in asset && (asset.box === null || typeof asset.box !== 'string')) delete asset.box; Type guard
const hasValidBox = (a) => !('box' in a) || (typeof a.box === 'string' && a.box !== null); Prevention
- Omit optional keys instead of setting them to null
- Configure serializers to drop undefined/null optional fields
- Only pass real notebook box ID strings
When it happens
Trigger: Sending {"index":0,"path":"/a.png","box":null} or box: 123 / box: {"id":"x"} in an asset of the /api/clipboard/prepareRichText payload.
Common situations: 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.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Field [assets. ] should be of type [Object]
- Field [groups. ] should be of type [String]
- attr must be a string or null (got %T)
- block [ ] type is locked: expected , got
- createDocTree definition must be a list
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/30ba2d8fac023b54.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/clipboard_input.go:37
return request, err
}
if len(assets) == 0 {
return request, fmt.Errorf("Field [assets] must not be empty")
}
request.Assets = make([]RichClipboardAsset, 0, len(assets))
for i, raw := range assets {
var asset map[string]json.RawMessage
if json.Unmarshal(raw, &asset) != nil || asset == nil {
return request, fmt.Errorf("Field [assets.%d] should be of type [Object]", i)
}
var index float64
var path, box string
if 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) == "" {
return request, fmt.Errorf("Invalid rich clipboard asset at index [%d]", i)
}
if value, exists := asset["box"]; exists {
if bytes.Equal(value, []byte("null")) || json.Unmarshal(value, &box) != nil {
return request, fmt.Errorf("Field [assets.%d.box] should be of type [String]", i)
}
}
request.Assets = append(request.Assets, RichClipboardAsset{Index: int(index), Path: strings.TrimSpace(path), Box: strings.TrimSpace(box)})
}
return
}
CleanupRichText.decodeRequest = func(reader io.Reader) (request CleanupRichTextRequest, err error) {
fields, err := blockRequestFields(reader, "/api/clipboard/cleanupRichText")
if err != nil {
return request, err
}
request.Batch, err = legacyField[string](fields, "batch", "String", true)
if err != nil {
return request, err
}
request.Batch = strings.TrimSpace(request.Batch)
if request.Batch == "" {
return request, fmt.Errorf("Field [batch] must not be empty")View on GitHub (pinned to 9f775e8a12)