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

  1. Pass a targetID that is currently pinned (fetch the list via GetPinnedDocs first).
  2. Do not include targetID in the ids array of the same call.
  3. Omit targetID (empty string) to append the new pins instead of inserting relative to an anchor.
  4. 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

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


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)