{"record":{"id":"0ac9f1081018fdbe","repo":"siyuan-note/siyuan","slug":"resolve-file-annotation-asset-s-w","errorCode":null,"errorMessage":"resolve file annotation asset [%s]: %w","messagePattern":"resolve file annotation asset \\[(.+?)\\]: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/export.go","lineNumber":4357,"sourceCode":"\tassetLink, annotationID := util.SplitFileAnnotationRef(refID)\n\tif \"\" == annotationID {\n\t\treturn fmt.Errorf(\"invalid file annotation reference [%s]\", refID)\n\t}\n\tp, query, _ := splitAssetReference(assetLink)\n\tassetLink = p\n\tif \"\" != query {\n\t\tassetLink += \"?\" + query\n\t}\n\tlookupLink := p\n\tif decodedPath, decodeErr := url.PathUnescape(p); nil == decodeErr {\n\t\tlookupLink = decodedPath\n\t}\n\tif \"\" != query {\n\t\tlookupLink += \"?\" + query\n\t}\n\tabsPath, err := GetAssetAbsPathInBox(lookupLink, boxID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"resolve file annotation asset [%s]: %w\", assetLink, err)\n\t}\n\tsya := absPath + \".sya\"\n\t// 以实际资源所属笔记本认证标注密文，读取失败时保留源文件并中止导出。\n\tassetBoxID := ExtractBoxIDFromAssetsPath(absPath)\n\tvar dek []byte\n\tif IsEncryptedBox(assetBoxID) {\n\t\tHoldBoxReadLock(assetBoxID)\n\t\tdefer ReleaseBoxReadLock(assetBoxID)\n\t\tdek, err = GetDEKIfUnlocked(assetBoxID)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer clear(dek)\n\t}\n\tsyaData, readErr := os.ReadFile(sya)\n\tif readErr != nil {\n\t\treturn fmt.Errorf(\"read file annotation [%s]: %w\", sya, readErr)\n\t}","sourceCodeStart":4339,"sourceCodeEnd":4375,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/export.go#L4339-L4375","documentation":"During PDF file-annotation export, the kernel resolves the asset link referenced by an annotation to an absolute path inside a notebook via GetAssetAbsPathInBox. When that lookup fails (asset missing, link malformed, or asset outside the box), export of that file annotation is aborted with this wrapped error, preserving the original source rather than exporting incomplete data.","triggerScenarios":"Calling the export path for a PDF whose .sya annotation asset link cannot be resolved: the asset was moved/renamed/deleted from the notebook's assets folder, the lookupLink is malformed (bad query suffix), or the asset belongs to a different box than boxID.","commonSituations":"Exporting a document after the referenced PDF was deleted or moved out of assets/; assets synced from another device where the file was removed; hand-edited markdown pointing to a wrong asset path; notebook ID mismatch when exporting across boxes.","solutions":["Verify the asset file exists in the notebook's assets folder at the path referenced by the annotation link","Re-insert or re-link the PDF annotation so the asset link points to an existing asset","Check the notebook (boxID) matches the notebook that actually owns the asset","Rebuild the asset reference by re-uploading the PDF and recreating the annotation"],"exampleFix":"// before: annotation points to a deleted asset\n![annotation](assets/old-report.pdf)\n// after: re-link to the existing asset\n![annotation](assets/report.pdf)","handlingStrategy":"validation","validationCode":"const assetPath = \"assets/report.pdf\";\nconst resp = await fetchPost(\"/api/filetree/getDocInfo\", {id: docID}); // confirm annotation link resolves\n// ensure the file exists before export:\nconst stat = await fetchPost(\"/api/file/getFileStat\", {path: assetPath});","typeGuard":null,"tryCatchPattern":"try {\n  await exportAnnotation(docID);\n} catch (e) {\n  if (/resolve file annotation asset/.test(e.message)) {\n    console.warn(\"Asset missing; re-link the PDF before exporting\", e.cause);\n  }\n}","preventionTips":["Never delete or move PDFs referenced by file annotations without re-linking","Keep annotation assets inside the owning notebook's assets folder","Run export after confirming notebooks are fully synced"],"tags":["export","assets","file-annotation","pdf"],"backgroundTag":"file-not-found","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"}