siyuan-note/siyuan · error
resolve asset [%s] failed: %w
Error message
resolve asset [%s] failed: %w
What it means
Thrown by ResolveDataAssetPath (kernel/model/assets.go:967) when filepath.EvalSymlinks fails on the specific asset file's absolute path. Unlike the assets-root errors, this is about the individual file: it fails when the file does not exist, is a broken symlink, or is inaccessible due to permissions.
Source
Thrown at kernel/model/assets.go:967
resolvedRoot, evalErr := filepath.EvalSymlinks(assetRoot)
if evalErr != nil {
err = fmt.Errorf("resolve assets directory [%s] failed: %w", assetRoot, evalErr)
return
}
if assetDirIndex > 0 {
notebookRoot := filepath.Join(util.DataDir, parts[0])
resolvedDataDir, dataEvalErr := filepath.EvalSymlinks(util.DataDir)
resolvedNotebookRoot, notebookEvalErr := filepath.EvalSymlinks(notebookRoot)
if dataEvalErr != nil || notebookEvalErr != nil ||
!gulu.File.IsSubPath(resolvedDataDir, resolvedNotebookRoot) ||
!gulu.File.IsSubPath(resolvedNotebookRoot, resolvedRoot) {
err = fmt.Errorf("notebook asset path resolves outside notebook directory: %s", assetPath)
return
}
}
resolvedPath, evalErr := filepath.EvalSymlinks(absPath)
if evalErr != nil {
err = fmt.Errorf("resolve asset [%s] failed: %w", absPath, evalErr)
return
}
if !gulu.File.IsSubPath(resolvedRoot, resolvedPath) {
err = fmt.Errorf("asset path resolves outside assets directory: %s", assetPath)
return
}
relativePath = filepath.ToSlash(dataRelativePath)
return
}
// ResolveUnusedDataAssetPath 解析 data 相对资源路径,并确认目标当前未被引用。
func ResolveUnusedDataAssetPath(assetPath string) (relativePath, absPath string, err error) {
relativePath, absPath, err = ResolveDataAssetPath(assetPath)
if err != nil {
return
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Verify the file at the printed absPath exists: `ls -la <absPath>`.
- If deleted, either restore from backup/history or remove the dangling reference from the document.
- If it is a broken symlink, recreate the target or remove the link.
- Fix read/traverse permissions on the file and its parent directories for the kernel process user.
Defensive patterns
Strategy: validation
Validate before calling
// Verify the asset file exists and is resolvable before calling the resolver, to give a clearer error.
abs := filepath.Join(util.DataDir, filepath.FromSlash(p))
if _, err := filepath.EvalSymlinks(abs); err != nil {
return fmt.Errorf("asset file missing or inaccessible: %w", err)
} Try / catch
_, absPath, err := model.ResolveDataAssetPath(p)
if err != nil {
if strings.Contains(err.Error(), "resolve asset [") {
// file-level resolution failure (deleted/dangling link/permissions); guide user to restore or remove reference
}
return err
} Prevention
- Treat asset references as soft: when a file is missing, offer to remove the broken reference instead of failing hard.
- Keep backups/history enabled so deleted assets can be restored.
- Avoid concurrent external processes that move/delete assets while the kernel runs.
When it happens
Trigger: Calling ResolveDataAssetPath for an asset that was deleted between the time the document referenced it and the time of resolution; resolving a path whose final component is a dangling symlink; resolving a file inside a directory the process cannot read/traverse.
Common situations: Stale references in a document after the user deleted the asset from disk; assets removed by an external sync/cleanup tool; a race where the file is being moved; permission mismatch after a user account change.
Related errors
- resolve assets directory [%s] failed: %w
- resolve assets root [%s] failed: %w
- asset path resolves outside assets directory: %s
- symlink [%s] resolves outside data/assets: [%s]
- read image failed: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/77507ef5c7f9aa0e.
Report an issue: GitHub.