{"record":{"id":"be043ce47e5f3b92","repo":"siyuan-note/siyuan","slug":"cannot-read-pinned-document-s","errorCode":null,"errorMessage":"cannot read pinned document [%s]","messagePattern":"cannot read pinned document \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/pinned_docs.go","lineNumber":130,"sourceCode":"\t\tbox := boxes[boxID]\n\t\tif box == nil || IsEncryptedBox(boxID) {\n\t\t\tcontinue\n\t\t}\n\t\tdoc := PinnedDoc{ID: ref.ID, Notebook: boxID, Name: ref.ID, Unavailable: box.Closed}\n\t\tif box.Closed {\n\t\t\tret = append(ret, doc)\n\t\t\tcontinue\n\t\t}\n\t\tif !isPinnableDocument(bt) {\n\t\t\tcontinue\n\t\t}\n\t\tinfo := box.Stat(bt.Path)\n\t\tif info == nil {\n\t\t\tcontinue\n\t\t}\n\t\tial := box.docIAL(bt.Path)\n\t\tif ial == nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot read pinned document [%s]\", ref.ID)\n\t\t}\n\t\tif ref.ID != boxID && ial[DocHiddenAttr] == \"true\" {\n\t\t\tcontinue\n\t\t}\n\t\tfile := box.docFromFileInfo(info, ial)\n\t\tif file == nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot read pinned document [%s]\", ref.ID)\n\t\t}\n\t\tdoc.Name, doc.Path, doc.Icon = file.Name, file.Path, file.Icon\n\t\tdoc.ChildrenSortMode = file.ChildrenSortMode\n\t\tif file.TitleEmpty {\n\t\t\tdoc.Name = Conf.Language(16)\n\t\t}\n\t\tif ref.ID == boxID {\n\t\t\tdoc.SubFileCount = BoxDocSubFileCount(boxID)\n\t\t} else {\n\t\t\tdoc.SubFileCount, err = visibleDocCount(boxID, strings.TrimSuffix(bt.Path, \".sy\"), box.docIAL, nil)\n\t\t\tif err != nil {","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/pinned_docs.go#L112-L148","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the .sy file for the pinned document exists and is valid JSON under data/<notebook>/<path>.sy","Repair the document (use SiYuan's data repair / history recovery) or unpin and re-pin the document","Check file permissions on the document file and its directory","Restore the .sy file from sync history or local history","Restart the kernel to clear transient file-lock issues"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Verify the .sy file parses before depending on the pin\nif data, err := os.ReadFile(syPath); err == nil {\n\tvar tree map[string]any\n\tif json.Unmarshal(data, &tree) != nil { /* .sy corrupted */ }\n}","typeGuard":null,"tryCatchPattern":"docs, err := GetPinnedDocs()\nif err != nil && strings.Contains(err.Error(), \"cannot read pinned document\") {\n\t// unpin the offending document or restore its .sy from history, then retry\n}","preventionTips":["Keep sync healthy; investigate incomplete-sync warnings promptly","Back up the data directory so corrupted .sy files can be restored","Avoid concurrent external edits of .sy files","Check disk health if document corruption recurs"],"tags":["go","file-io","documents","storage"],"backgroundTag":"file-read-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}