siyuan-note/siyuan · error

prepare export asset [%s]: %w

Error message

prepare export asset [%s]: %w

What it means

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.).

Source

Thrown at kernel/model/asset_download_read.go:269

		}
		for _, dest := range dests {
			dest = string(html.DecodeDestination([]byte(dest)))
			if fragment := strings.IndexByte(dest, '#'); fragment >= 0 {
				dest = dest[:fragment]
			}
			if !strings.HasPrefix(AssetPathWithoutQuery(dest), "assets/") {
				continue
			}
			absPath, resolveErr := GetAssetAbsPathInBox(dest, tree.Box)
			if resolveErr != nil {
				return resolveErr
			}
			assets[absPath] = true
		}
	}
	for absPath := range assets {
		if err = EnsureAssetPrefixLocal(absPath); err != nil {
			return fmt.Errorf("prepare export asset [%s]: %w", filepath.Base(absPath), err)
		}
	}
	return nil
}

func prepareExportBlockAssets(id string, includeSubDocs bool) error {
	bt := getExportBlockTree(id)
	if bt == nil {
		return nil
	}
	docPaths := []string{bt.Path}
	if includeSubDocs {
		if box := Conf.Box(bt.BoxID); box != nil {
			listPath := strings.TrimSuffix(bt.Path, ".sy")
			if IsBoxDoc(bt.BoxID, bt.RootID) {
				listPath = "/"
			}
			for _, file := range box.ListFiles(listPath) {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Read the wrapped %w cause in logs to identify the root failure and fix it (network, credentials, broken symlink)
  2. Ensure the referenced assets exist locally (open the docs once with the asset-download pipeline active) before exporting
  3. Repair broken asset references or symlinks in the source document (see errors 603-605)
  4. Retry the export after restoring cloud repo connectivity

Example fix

// before
model.ExportSYZip(boxID, ...) // 'prepare export asset [img.png]: chunk download failed'
// after
if err := checkCloudRepoReachable(); err != nil {
    return fmt.Errorf("export aborted, cloud repo unreachable: %w", err)
}
model.ExportSYZip(boxID, ...)
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: ensure assets resolve locally before export
for _, p := range referencedAssetPaths(docID) {
    if _, err := model.ResolveDataAssetPath(p); err != nil {
        return fmt.Errorf("asset %s unresolvable: %w", p, err)
    }
}

Try / catch

err := model.ExportSYZip(boxID, paths, name, false)
if err != nil && strings.HasPrefix(err.Error(), "prepare export asset [") {
    var base, cause error
    if _, werr := fmt.Sscanf(err.Error(), "prepare export asset [%s", &base); werr == nil {
        log.Errorf("export blocked on asset %v", base)
    }
    return fmt.Errorf("fix the listed asset (network/symlink/lock) and retry: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/60fa1383eba088a4. Report an issue: GitHub.