siyuan-note/siyuan · error
asset path must be absolute
Error message
asset path must be absolute
What it means
dataRelativeAssetPath validates that an asset path is absolute before converting it to a data-directory-relative slash path. SiYuan throws this because a relative path cannot be safely related to util.DataDir, which would produce a meaningless or dangerous result.
Source
Thrown at kernel/model/asset_download.go:117
if Conf.Sync == nil || !Conf.Sync.Enabled || Conf.GetUser() == nil {
return errors.New(Conf.Language(376))
}
switch Conf.Sync.Provider {
case conf.ProviderSiYuan:
if !IsSubscriber() {
return errors.New(Conf.Language(376))
}
case conf.ProviderS3, conf.ProviderWebDAV, conf.ProviderLocal:
if !IsPaidUser() {
return errors.New(Conf.Language(376))
}
}
return nil
}
func dataRelativeAssetPath(absPath string) (string, error) {
if !filepath.IsAbs(absPath) {
return "", fmt.Errorf("asset path must be absolute")
}
rel, err := filepath.Rel(util.DataDir, filepath.Clean(absPath))
if err != nil || rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
return "", fmt.Errorf("asset path is outside data directory")
}
if rel == "." {
return "/", nil
}
return "/" + filepath.ToSlash(rel), nil
}
// EnsureAssetLocal 在调用方完成访问校验后补齐资源,下载内容仍由原有读取流程认证。
func EnsureAssetLocal(absPath string) error {
if _, err := os.Stat(absPath); err == nil {
return nil
} else if !errors.Is(err, os.ErrNotExist) {
return err
}View on GitHub (pinned to 8641553a1f)
Solutions
- Resolve the path to absolute before calling, e.g. filepath.Join(util.DataDir, relPath)
- Check filepath.IsAbs(path) before invoking the API
- Use GetAssetAbsPath or a similar API that returns absolute paths
Example fix
// before
err := model.EnsureAssetLocal("assets/foo.png")
// after
abs := filepath.Join(util.DataDir, "assets/foo.png")
err := model.EnsureAssetLocal(abs) Defensive patterns
Strategy: validation
Validate before calling
if !filepath.IsAbs(p) {
p = filepath.Join(util.DataDir, p)
} Prevention
- Always resolve asset paths to absolute before calling EnsureAssetLocal/EnsureAssetPrefixLocal
- Store absolute paths or convert early at ingestion boundaries
- Add a filepath.IsAbs assertion in dev builds
When it happens
Trigger: Passing a relative path (e.g. "assets/foo.png") to EnsureAssetLocal or EnsureAssetPrefixLocal instead of an absolute filesystem path.
Common situations: Storing asset paths from database fields that hold relative paths; passing user-supplied or UI-derived paths without resolving them against the workspace; using paths returned from APIs that document relative results.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- path is not under an assets directory: %s
- path is not a child of assets directory: %s
- source is not an encrypted asset
- --path must not be empty
- --path is required
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/5e4642b868ab84ee.
Report an issue: GitHub.