{"record":{"id":"60fa1383eba088a4","repo":"siyuan-note/siyuan","slug":"prepare-export-asset-s-w","errorCode":null,"errorMessage":"prepare export asset [%s]: %w","messagePattern":"prepare export asset \\[(.+?)\\]: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/asset_download_read.go","lineNumber":269,"sourceCode":"\t\t}\n\t\tfor _, dest := range dests {\n\t\t\tdest = string(html.DecodeDestination([]byte(dest)))\n\t\t\tif fragment := strings.IndexByte(dest, '#'); fragment >= 0 {\n\t\t\t\tdest = dest[:fragment]\n\t\t\t}\n\t\t\tif !strings.HasPrefix(AssetPathWithoutQuery(dest), \"assets/\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tabsPath, resolveErr := GetAssetAbsPathInBox(dest, tree.Box)\n\t\t\tif resolveErr != nil {\n\t\t\t\treturn resolveErr\n\t\t\t}\n\t\t\tassets[absPath] = true\n\t\t}\n\t}\n\tfor absPath := range assets {\n\t\tif err = EnsureAssetPrefixLocal(absPath); err != nil {\n\t\t\treturn fmt.Errorf(\"prepare export asset [%s]: %w\", filepath.Base(absPath), err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc prepareExportBlockAssets(id string, includeSubDocs bool) error {\n\tbt := getExportBlockTree(id)\n\tif bt == nil {\n\t\treturn nil\n\t}\n\tdocPaths := []string{bt.Path}\n\tif includeSubDocs {\n\t\tif box := Conf.Box(bt.BoxID); box != nil {\n\t\t\tlistPath := strings.TrimSuffix(bt.Path, \".sy\")\n\t\t\tif IsBoxDoc(bt.BoxID, bt.RootID) {\n\t\t\t\tlistPath = \"/\"\n\t\t\t}\n\t\t\tfor _, file := range box.ListFiles(listPath) {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/asset_download_read.go#L251-L287","documentation":"After collecting all assets referenced by the export trees, prepareExportAssets calls EnsureAssetPrefixLocal for each absolute path to complete any missing local prefix chunks (downloading raw ciphertext where needed). A failure is wrapped as 'prepare export asset [<basename>]: %w', identifying the offending asset file while preserving the underlying cause (network, locked box, path-traversal guard, etc.).","triggerScenarios":"exportSYZip / exportPandocConvertZip0 / prepareExportBlockAssets on a document whose referenced assets are not fully present locally and whose prefix download fails — e.g. cloud repo unreachable, or the asset path trips a guard from errors 603-605.","commonSituations":"Exporting on a new machine where deferred asset downloads haven't completed and network is down; an asset reference is a dangling symlink or escapes the notebook (rejected by resolution guards); cloud credentials expired mid-export.","solutions":["Read the wrapped %w cause in logs to identify the root failure and fix it (network, credentials, broken symlink)","Ensure the referenced assets exist locally (open the docs once with the asset-download pipeline active) before exporting","Repair broken asset references or symlinks in the source document (see errors 603-605)","Retry the export after restoring cloud repo connectivity"],"exampleFix":"// before\nmodel.ExportSYZip(boxID, ...) // 'prepare export asset [img.png]: chunk download failed'\n// after\nif err := checkCloudRepoReachable(); err != nil {\n    return fmt.Errorf(\"export aborted, cloud repo unreachable: %w\", err)\n}\nmodel.ExportSYZip(boxID, ...)","handlingStrategy":"try-catch","validationCode":"// pre-flight: ensure assets resolve locally before export\nfor _, p := range referencedAssetPaths(docID) {\n    if _, err := model.ResolveDataAssetPath(p); err != nil {\n        return fmt.Errorf(\"asset %s unresolvable: %w\", p, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := model.ExportSYZip(boxID, paths, name, false)\nif err != nil && strings.HasPrefix(err.Error(), \"prepare export asset [\") {\n    var base, cause error\n    if _, werr := fmt.Sscanf(err.Error(), \"prepare export asset [%s\", &base); werr == nil {\n        log.Errorf(\"export blocked on asset %v\", base)\n    }\n    return fmt.Errorf(\"fix the listed asset (network/symlink/lock) and retry: %w\", err)\n}","preventionTips":["Pre-download assets (DeferredSyncAssets / opening docs) before exporting on fresh machines","Keep cloud repo credentials valid so prefix downloads succeed","Fix any dangling symlinks or escaping asset links flagged by resolution guards","Parse the asset basename from the wrapped message to target the fix precisely"],"tags":["export","assets","network"],"backgroundTag":"network-request-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}