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

  1. Ensure at least one document ID is passed in the ids parameter of the update call
  2. Fix the frontend/plugin caller to guard against empty selections before invoking the API
  3. 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

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


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] {
			continue

View on GitHub (pinned to 9f775e8a12)