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

  1. Resolve the path to absolute before calling, e.g. filepath.Join(util.DataDir, relPath)
  2. Check filepath.IsAbs(path) before invoking the API
  3. 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

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


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