{"record":{"id":"a5929def2dd9f246","repo":"siyuan-note/siyuan","slug":"unsupported-pinned-documents-version-d","errorCode":null,"errorMessage":"unsupported pinned documents version [%d]","messagePattern":"unsupported pinned documents version \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/pinned_docs.go","lineNumber":57,"sourceCode":"func isPinnableDocument(tree *treenode.BlockTree) bool {\n\treturn tree != nil && tree.ID == tree.RootID && tree.Type == \"d\" && !IsEncryptedBox(tree.BoxID)\n}\n\nfunc readPinnedDocs() (ret pinnedDocsStorage, err error) {\n\tret = pinnedDocsStorage{Version: 1, Docs: []pinnedDocRef{}}\n\tdata, err := filelock.ReadFile(filepath.Join(util.DataDir, \"storage\", \"pinned-docs.json\"))\n\tif os.IsNotExist(err) {\n\t\treturn ret, nil\n\t}\n\tif err != nil {\n\t\treturn\n\t}\n\tret = pinnedDocsStorage{}\n\tif err = json.Unmarshal(data, &ret); err != nil {\n\t\treturn\n\t}\n\tif ret.Version != 1 || ret.Docs == nil {\n\t\treturn ret, fmt.Errorf(\"unsupported pinned documents version [%d]\", ret.Version)\n\t}\n\tseen := map[string]bool{}\n\tfor _, doc := range ret.Docs {\n\t\tif !ast.IsNodeIDPattern(doc.ID) || !ast.IsNodeIDPattern(doc.Notebook) || seen[doc.ID] {\n\t\t\treturn ret, fmt.Errorf(\"invalid pinned document [%s]\", doc.ID)\n\t\t}\n\t\tseen[doc.ID] = true\n\t}\n\treturn\n}\n\nfunc writePinnedDocs(data pinnedDocsStorage) error {\n\tencoded, err := json.Marshal(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdir := filepath.Join(util.DataDir, \"storage\")\n\tif err = os.MkdirAll(dir, 0755); err != nil {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/pinned_docs.go#L39-L75","documentation":"readPinnedDocs validates storage/pinned-docs.json and throws \"unsupported pinned documents version [%d]\" when the stored version field is not 1 or the docs array is missing (null). This guards against corrupt or future-format files written by a newer SiYuan version.","triggerScenarios":"Loading pinned documents (GetPinnedDocs, UpdatePinnedDocs, maintainPinnedDocs) where pinned-docs.json has version != 1 or docs == null — e.g. hand-edited file, truncated/corrupt file, or file written by a newer schema.","commonSituations":"Manually editing pinned-docs.json and omitting version or docs; restoring a partial file from backup; a newer/older SiYuan version with a different schema wrote the file; JSON with \"docs\": null.","solutions":["Open data/storage/pinned-docs.json and confirm it contains {\"version\":1,\"docs\":[...]}","Fix or remove the invalid version/docs field, or delete the file to reset pins to empty","Restore pinned-docs.json from a working backup or from sync history","If a version upgrade introduced this, downgrade or upgrade SiYuan so versions match"],"exampleFix":"// before (corrupt storage file)\n{\"version\":2,\"docs\":[{\"id\":\"20240101120000-abc1234\",\"notebook\":\"20240101120000-box5678\"}]}\n// after (supported schema)\n{\"version\":1,\"docs\":[{\"id\":\"20240101120000-abc1234\",\"notebook\":\"20240101120000-box5678\"}]}","handlingStrategy":"validation","validationCode":"// Validate the storage file before loading pinned docs\nvar raw map[string]any\njson.Unmarshal(data, &raw)\nv, _ := raw[\"version\"].(float64)\n_, ok := raw[\"docs\"]\nif v != 1 || !ok { /* reset or repair pinned-docs.json */ }","typeGuard":null,"tryCatchPattern":"docs, err := GetPinnedDocs()\nif err != nil && strings.Contains(err.Error(), \"unsupported pinned documents version\") {\n\tos.Remove(filepath.Join(util.DataDir, \"storage\", \"pinned-docs.json\")) // reset\n\tdocs, err = GetPinnedDocs()\n}","preventionTips":["Do not hand-edit pinned-docs.json; use the UI pin actions","Keep version and docs fields intact if editing manually","Back up the storage directory before upgrading SiYuan versions","Treat schema-versioned files as opaque across app versions"],"tags":["go","json","storage","schema"],"backgroundTag":"schema-validation-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"}