{"record":{"id":"23b4e9ec89d5e299","repo":"siyuan-note/siyuan","slug":"invalid-annotation-file","errorCode":null,"errorMessage":"invalid annotation file","messagePattern":"invalid annotation file","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/asset_relink.go","lineNumber":444,"sourceCode":"\tif _, statErr := os.Stat(source); statErr == nil {\n\t\tif err := validateRelinkStoragePath(source); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tdata, err := filelock.ReadFile(source)\n\tif os.IsNotExist(err) {\n\t\tfor i := range p.result.References {\n\t\t\tif p.result.References[i].Type == \"annotation\" && p.result.References[i].OldPath == p.oldPath {\n\t\t\t\tp.result.References[i].Relinkable, p.result.References[i].Reason = false, \"annotation_file_missing\"\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !json.Valid(data) || util.IsCiphertext(data) {\n\t\treturn errors.New(\"invalid annotation file\")\n\t}\n\tref := apicontract.AssetReference{OldPath: p.oldPath, Type: \"annotation-file\", Path: p.oldPath + \".sya\", Reference: p.oldPath, Relinkable: true}\n\tif p.newPath != \"\" {\n\t\tref.Replacement = p.newPath\n\t\tif !strings.EqualFold(filepath.Ext(p.newPath), \".pdf\") {\n\t\t\tref.Relinkable, ref.Reason = false, \"annotation_requires_pdf\"\n\t\t} else if target, readErr := filelock.ReadFile(newAbs + \".sya\"); readErr == nil {\n\t\t\tif !bytes.Equal(data, target) {\n\t\t\t\tref.Relinkable, ref.Reason = false, \"annotation_target_conflict\"\n\t\t\t}\n\t\t} else if !os.IsNotExist(readErr) {\n\t\t\treturn readErr\n\t\t} else {\n\t\t\titems := p.itemsForPath(p.oldPath)\n\t\t\tp.files = append(p.files, &assetRelinkFile{path: source, before: data, backupOnly: true, items: items})\n\t\t\tp.files = append(p.files, &assetRelinkFile{path: newAbs + \".sya\", after: data, items: items})\n\t\t}\n\t}","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/asset_relink.go#L426-L462","documentation":"PDF annotations are stored as <pdf>.sya files next to the PDF and must be valid, non-encrypted JSON. During scanAnnotation, if the source .sya file exists but its bytes are not valid JSON or look like ciphertext, the scan aborts because annotation relinking requires parsing and copying this data.","triggerScenarios":"scanMetadata calls scanAnnotation for a PDF asset that has annotations; filelock.ReadFile returns data where json.Valid(data) is false or util.IsCiphertext(data) is true for the <old>.sya file.","commonSituations":"The .sya file was truncated by a crashed write; it was encrypted/obfuscated by an external tool or sync layer; the file was replaced by unrelated binary content; corruption during an interrupted sync.","solutions":["Restore the .sya file from history/backup or from the sync source","Verify the file with a JSON validator after restoring before re-running the scan","If annotations are unrecoverable, delete the .sya file so annotations are reported as missing instead of failing the scan","Check the sync/encryption tooling so .sya files are transported as plaintext JSON"],"exampleFix":"// before\n// assets/paper.pdf.sya contains non-JSON ciphertext\n// after\ncp(\"history/.../assets/paper.pdf.sya\", \"data/assets/paper.pdf.sya\")\n// verify: json.Valid(readFile(path)) == true","handlingStrategy":"validation","validationCode":"// validate the .sya annotation file before relinking\ndata, err := os.ReadFile(pdfPath + \".sya\")\nif err != nil || !json.Valid(data) {\n\t// restore from backup or remove stale annotations\n}","typeGuard":null,"tryCatchPattern":"// handle invalid annotation data gracefully\nif err := plan.Scan(); err != nil {\n\tif err.Error() == \"invalid annotation file\" {\n\t\t// restore <pdf>.sya from history, then retry\n\t}\n\treturn err\n}","preventionTips":["Do not modify or encrypt .sya files externally","Ensure sync transports .sya files verbatim as plaintext JSON","Keep backups of .sya files alongside their PDFs"],"tags":["annotation","json","encryption","pdf"],"backgroundTag":"invalid-json-response","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"}