{"record":{"id":"443dad305ab6d367","repo":"siyuan-note/siyuan","slug":"the-document-spec-is-too-new","errorCode":null,"errorMessage":"the document spec is too new","messagePattern":"the document spec is too new","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/treenode/tree.go","lineNumber":152,"sourceCode":"\tret = &ast.Node{ID: newID, Type: ast.NodeParagraph}\n\tret.SetIALAttr(\"id\", newID)\n\tret.SetIALAttr(\"updated\", newID[:14])\n\treturn\n}\n\nfunc NewSpanAnchor(id string) (ret *ast.Node) {\n\treturn &ast.Node{Type: ast.NodeInlineHTML, Tokens: []byte(\"<span id=\\\"\" + id + \"\\\" style=\\\"display: none;\\\"></span>\")}\n}\n\nfunc ContainOnlyDefaultIAL(tree *parse.Tree) bool {\n\treturn 5 > len(tree.Root.KramdownIAL)\n}\n\nconst BaseSpec = \"2\"\n\nvar CurrentSpec = \"4\"\n\nvar ErrSpecTooNew = fmt.Errorf(\"the document spec is too new\")\n\n// CheckSpecJSON 在解析节点之前检查文档规范，避免未知节点被容错解析后覆盖原始内容。\nfunc CheckSpecJSON(data []byte) error {\n\tvar root struct {\n\t\tSpec string\n\t}\n\tif err := json.Unmarshal(data, &root); nil != err {\n\t\treturn err\n\t}\n\tif err := CheckSpec(&parse.Tree{Root: &ast.Node{Spec: root.Spec}}); nil != err {\n\t\treturn err\n\t}\n\treturn checkTableCellRichJSON(data, root.Spec)\n}\n\nfunc CheckSpec(tree *parse.Tree) (err error) {\n\tif err = ValidateTableCellRich(tree.Root); nil != err {\n\t\treturn","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/treenode/tree.go#L134-L170","documentation":"ErrSpecTooNew is a sentinel error returned when a .sy document's Spec field is greater than the kernel's CurrentSpec, meaning the file was written by a newer SiYuan version with node/attribute formats this kernel cannot safely parse. Parsing is refused to avoid unknown nodes being tolerance-parsed and overwriting the original content.","triggerScenarios":"Opening, rendering an attribute view, or fetching a block (CheckSpec / renderAttrView / setGetBlockInfoError paths) from a workspace whose documents were written by a newer SiYuan version; downgrading the app while keeping the same data directory.","commonSituations":"User rolled back from a newer release/beta to an older stable; sync brought documents created by a newer client into an older one; opening a newer mobile-created doc on an old desktop version.","solutions":["Upgrade SiYuan to a version whose CurrentSpec is >= the document's spec","Do not open this data directory with the older version; copy data back to the newer installation","Exclude/move the too-new documents from the workspace if you must stay on the old version (risk of data loss)","Check kernel logs for the logged spec numbers to confirm the version mismatch"],"exampleFix":"// before: downgraded kernel sees Spec \"4\" > CurrentSpec \"2\"\n// after: run a kernel with matching CurrentSpec\nvar CurrentSpec = \"4\" // must be >= document Spec\nif err := treenode.CheckSpecJSON(data); errors.Is(err, treenode.ErrSpecTooNew) { upgrade() }","handlingStrategy":"fallback","validationCode":"// Check spec before opening the data dir\nconst spec = parseInt(JSON.parse(syFile).Root.Spec, 10);\nif (spec > CURRENT_SPEC) { upgradeRequired = true; }","typeGuard":null,"tryCatchPattern":"if errors.Is(err, treenode.ErrSpecTooNew) {\n  return localizedMsg(model.Conf.Language(275)) // prompt user to upgrade\n}","preventionTips":["Never downgrade the app while keeping a newer data directory","Pin all synced devices to the same SiYuan version","Back up data before version changes","Read release notes for document spec bumps"],"tags":["versioning","compatibility","document-spec"],"backgroundTag":"incompatible-source-type","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"}