siyuan-note/siyuan · warning
document IDs are required
Error message
document IDs are required
What it means
Validation guard at the start of UpdatePinnedDocs: fires when the ids slice is empty or nil. Updating pinned-document order or pin state requires at least one document ID; callers passing an empty list (e.g. no pinned entries to reorder) hit this before the action validity check.
Solutions
- Ensure at least one document ID is passed in the ids parameter of the update call
- Fix the frontend/plugin caller to guard against empty selections before invoking the API
- Re-select the documents in the file tree and retry the pin/unpin action
Example fix
// before (caller)
await fetchPost("/api/filetree/updatePinnedDocs", {ids: [], action: "pin"});
// after
if (!ids.length) return; // nothing selected
await fetchPost("/api/filetree/updatePinnedDocs", {ids, action: "pin"}); Defensive patterns
Strategy: validation
Validate before calling
// Caller-side guard before invoking the update API
if ids == nil || len(ids) == 0 {
return errors.New("select at least one document to pin/unpin")
} Try / catch
err := UpdatePinnedDocs(ids, "pin", "", false)
if err != nil && strings.Contains(err.Error(), "document IDs are required") {
// surface a user-facing 'no documents selected' hint
} Prevention
- Guard UI actions so pin/unpin only fires with a selection
- Deduplicate and filter empty strings out of ids before calling
- In plugins/scripts, assert ids non-empty before the API call
- Log the payload when the API rejects input to catch frontend regressions
When it happens
Trigger: Calling the pinned-docs update API (kernel API / pin action from the file tree) with an empty ids array — e.g. frontend bug sending no selection, or a plugin/script calling the endpoint with no documents selected.
Common situations: Automated scripts or plugins invoking the API with an empty list; frontend state where the selected document list was cleared before submit; race where documents were unpinned by another window before the call.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- invalid pinned document action
- invalid reorder position
- target ID [ ] must not be included in source IDs
- AI editor action must not be empty
- all asset mappings failed
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/f4930584fc4431d6.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/pinned_docs.go:160
doc.Name = Conf.Language(16)
}
if ref.ID == boxID {
doc.SubFileCount = BoxDocSubFileCount(boxID)
} else {
doc.SubFileCount, err = visibleDocCount(boxID, strings.TrimSuffix(bt.Path, ".sy"), box.docIAL, nil)
if err != nil {
return nil, err
}
}
ret = append(ret, doc)
}
return
}
// 根层顺序独立于源文档顺序,按相对位置更新以保留其他窗口新增的入口。
func UpdatePinnedDocs(ids []string, action, targetID string, after bool) error {
if len(ids) == 0 {
return fmt.Errorf("document IDs are required")
}
if action != "pin" && action != "unpin" {
return fmt.Errorf("invalid pinned document action")
}
pinnedDocsLock.Lock()
defer pinnedDocsLock.Unlock()
stored, err := readPinnedDocs()
if err != nil {
return err
}
selected := map[string]bool{}
refs := []pinnedDocRef{}
for _, id := range ids {
if !ast.IsNodeIDPattern(id) {
return fmt.Errorf("invalid document ID [%s]", id)
}
if selected[id] {
continueView on GitHub (pinned to 9f775e8a12)