siyuan-note/siyuan · error

cannot read pinned document

Error message

cannot read pinned document [%s]

What it means

GetPinnedDocs throws "cannot read pinned document [%s]" when box.docIAL(path) returns nil — i.e. the .sy file for a pinned document cannot be parsed/read to obtain its IAL attributes, even though Stat succeeded. It aborts the whole pinned-docs listing so the user knows a pin points to unreadable data.

Solutions

  1. Verify the .sy file for the pinned document exists and is valid JSON under data/<notebook>/<path>.sy
  2. Repair the document (use SiYuan's data repair / history recovery) or unpin and re-pin the document
  3. Check file permissions on the document file and its directory
  4. Restore the .sy file from sync history or local history
  5. Restart the kernel to clear transient file-lock issues
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the .sy file parses before depending on the pin
if data, err := os.ReadFile(syPath); err == nil {
	var tree map[string]any
	if json.Unmarshal(data, &tree) != nil { /* .sy corrupted */ }
}

Try / catch

docs, err := GetPinnedDocs()
if err != nil && strings.Contains(err.Error(), "cannot read pinned document") {
	// unpin the offending document or restore its .sy from history, then retry
}

Prevention

When it happens

Trigger: Listing pinned documents where a doc's .sy file exists per Stat but its IAL cannot be read: file corrupted, invalid JSON content, file lock/permission problem, or the file changed between Stat and docIAL.

Common situations: Interrupted sync left a truncated .sy file; disk corruption; the file was deleted/replaced between the Stat and IAL read (race); permission changes on data/ subdir.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/be043ce47e5f3b92. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/pinned_docs.go:130

		box := boxes[boxID]
		if box == nil || IsEncryptedBox(boxID) {
			continue
		}
		doc := PinnedDoc{ID: ref.ID, Notebook: boxID, Name: ref.ID, Unavailable: box.Closed}
		if box.Closed {
			ret = append(ret, doc)
			continue
		}
		if !isPinnableDocument(bt) {
			continue
		}
		info := box.Stat(bt.Path)
		if info == nil {
			continue
		}
		ial := box.docIAL(bt.Path)
		if ial == nil {
			return nil, fmt.Errorf("cannot read pinned document [%s]", ref.ID)
		}
		if ref.ID != boxID && ial[DocHiddenAttr] == "true" {
			continue
		}
		file := box.docFromFileInfo(info, ial)
		if file == nil {
			return nil, fmt.Errorf("cannot read pinned document [%s]", ref.ID)
		}
		doc.Name, doc.Path, doc.Icon = file.Name, file.Path, file.Icon
		doc.ChildrenSortMode = file.ChildrenSortMode
		if file.TitleEmpty {
			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 {

View on GitHub (pinned to 9f775e8a12)