siyuan-note/siyuan · error
pinned target [ ] is unavailable
Error message
pinned target [%s] is unavailable
What it means
When pinning with a targetID, UpdatePinnedDocs searches the remaining (already-pinned) refs for the target to compute the insertion position. If targetID is not currently pinned (or was itself removed by this same update because it is in ids), no insertion anchor exists and the kernel returns this error instead of guessing a position.
Solutions
- Pass a targetID that is currently pinned (fetch the list via GetPinnedDocs first).
- Do not include targetID in the ids array of the same call.
- Omit targetID (empty string) to append the new pins instead of inserting relative to an anchor.
- Refresh the pinned list in the caller after concurrent updates from other windows.
Example fix
// before
model.UpdatePinnedDocs([]string{newID, targetID}, "pin", targetID, true)
// after
model.UpdatePinnedDocs([]string{newID}, "pin", targetID, true) Defensive patterns
Strategy: validation
Validate before calling
pinned := model.GetPinnedDocs()
anchorOK := false
for _, d := range pinned {
if d.ID == targetID { anchorOK = true; break }
}
if !anchorOK { targetID = "" } // fall back to append Try / catch
if err := model.UpdatePinnedDocs(ids, "pin", targetID, after); err != nil {
if strings.Contains(err.Error(), "pinned target") {
// re-fetch pinned list and retry with empty targetID (append)
}
} Prevention
- Fetch the current pinned list immediately before anchored inserts
- Never include targetID in the ids array of the same call
- Fall back to append (empty targetID) when the anchor cannot be verified
- Refresh UI state after concurrent pin changes from other windows
When it happens
Trigger: Calling UpdatePinnedDocs(ids, "pin", targetID, after) where targetID is not in the current pinned list, is misspelled, was deleted, or is included in ids itself so it was filtered out of `remaining`.
Common situations: Plugin computes the anchor from a stale pinned list after another window changed the order; target doc was just unpinned in the same call (passed in both ids and targetID); UI passes an anchor that was never pinned.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- asset path must be absolute
- block [ ] type is a leaf block and cannot have children…
- Conf.Language(396)
- create a skill before creating its subdirectories
- document block [ ] cannot be used as a previous sibling…
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/bcb6ddc855479dad.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/pinned_docs.go:223
return nil
}
remaining := []pinnedDocRef{}
for _, ref := range stored.Docs {
if !selected[ref.ID] {
remaining = append(remaining, ref)
}
}
index := 0
if targetID != "" && action == "pin" {
index = -1
for i, ref := range remaining {
if ref.ID == targetID {
index = i
break
}
}
if index < 0 {
return fmt.Errorf("pinned target [%s] is unavailable", targetID)
}
if after {
index++
}
}
result := append([]pinnedDocRef{}, remaining[:index]...)
result = append(result, refs...)
result = append(result, remaining[index:]...)
if slices.Equal(stored.Docs, result) {
return nil
}
stored.Docs = result
return writePinnedDocs(stored)
}
// 源文档删除或跨笔记本移动后维护入口,异常配置保留原文件并记录错误。
func maintainPinnedDocs(ids map[string]bool, notebook, destination string) {
pinnedDocsLock.Lock()View on GitHub (pinned to 9f775e8a12)