siyuan-note/siyuan · error
Field [groups. ] should be of type [String]
Error message
Field [groups.%d] should be of type [String]
What it means
Request-validation error for the clipboard batch-input API: the element at index %d of the groups array is not a JSON string (null or another type), so the batch groups payload is malformed and the request is rejected before processing.
Solutions
- Send group identifiers as plain strings, e.g. groups: ["g1", "g2"]
- Map object arrays to their ID strings before sending (groups.map(g => g.id))
- Filter out null/undefined entries before serializing the payload
Example fix
// before
{groups: [{id: "g1"}]}
// after
{groups: ["g1"]} Defensive patterns
Strategy: type-guard
Validate before calling
const isStringArray = (g) => Array.isArray(g) && g.every((x) => typeof x === 'string' && x !== null);
Type guard
const isStringArray = (v) => Array.isArray(v) && v.every((x) => typeof x === 'string');
Prevention
- Map group objects to ID strings before sending
- Filter null/undefined entries from the array
- Avoid sparse arrays when building groups
When it happens
Trigger: Sending {"groups":[null]}, {"groups":[123]}, or {"groups":[{"id":"g1"}]} to /api/clipboard/cleanupRichText instead of an array of plain strings.
Common situations: Group objects serialized instead of their ID strings (missing .map(g => g.id)); null entries introduced by sparse arrays or failed lookups; mixing numeric group indexes with string IDs after a schema change.
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. .box] should be of type [String]
- Field [assets. ] should be of type [Object]
- 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/09e8927b7c2fd480.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/clipboard_input.go:68
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")
}
groups, err := legacyField[[]json.RawMessage](fields, "groups", "Array", true)
if err != nil {
return request, err
}
request.Groups = make([]string, 0, len(groups))
if len(groups) == 0 {
return request, fmt.Errorf("Field [groups] must not be empty")
}
for i, raw := range groups {
var group string
if bytes.Equal(raw, []byte("null")) || json.Unmarshal(raw, &group) != nil {
return request, fmt.Errorf("Field [groups.%d] should be of type [String]", i)
}
request.Groups = append(request.Groups, group)
}
return
}
}
View on GitHub (pinned to 9f775e8a12)