siyuan-note/siyuan · error

symbolic links in notebook are not supported

Error message

symbolic links in notebook are not supported: %s

What it means

During the notebook scan, the directory walk encounters a filesystem entry whose mode includes os.ModeSymlink. The relink engine refuses to scan notebooks containing symbolic links because symlinks can point outside the notebook, making reference scanning and asset resolution unreliable and unsafe.

Solutions

  1. Find the offending symlink at the reported absolute path and remove it, replacing it with a real copy of the target if needed.
  2. Re-run the relink with dryRun=true to confirm no other symlinks remain (the scan stops at the first one).
  3. Exclude symlinked content from the notebook, or move shared assets into a location the scan supports.
  4. Avoid tools that create symlinks inside the SiYuan data directory (e.g. use hard copies or the app's own sync).

Example fix

// before (shell)
ln -s /shared/assets data/notebooks/xxx/assets/shared
// after (shell)
cp -r /shared/assets data/notebooks/xxx/assets/shared
Defensive patterns

Strategy: validation

Validate before calling

filepath.WalkDir(boxDir, func(p string, d fs.DirEntry, err error) error {
    if d != nil && d.Type()&os.ModeSymlink != 0 {
        return fmt.Errorf("symlink found: %s", p)
    }
    return nil
})

Try / catch

if err := runRelink(); err != nil {
    var pathErr *os.PathError
    if strings.HasPrefix(err.Error(), "symbolic links in notebook") {
        // prompt user to remove the symlink at the reported path and retry
    }
}

Prevention

When it happens

Trigger: Running FindAssetReferences/RelinkAsset on a notebook directory tree that contains any symlink (file or directory) anywhere the walker traverses, e.g. a symlinked assets subdirectory or a symlinked .sy document; entry.Type()&os.ModeSymlink != 0 triggers the error with the absolute path.

Common situations: Sync tools (Dropbox, git with symlinked files, rsync -s) created symlinks inside data/; a developer linked a shared assets folder into a notebook; restoring a workspace backup on a filesystem (Windows FAT/exFAT) that materialized links oddly.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/64caf800d02e5b95. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/asset_relink.go:137

		}
		boxID := entry.Name()
		if !entry.IsDir() || !ast.IsNodeIDPattern(boxID) {
			continue
		}
		if IsEncryptedBox(boxID) {
			p.result.SkippedNotebooks = append(p.result.SkippedNotebooks, boxID)
			continue
		}
		boxDir := filepath.Join(util.DataDir, boxID)
		err = filepath.WalkDir(boxDir, func(absPath string, entry fs.DirEntry, walkErr error) error {
			if walkErr != nil {
				return walkErr
			}
			if err := p.checkContext(); err != nil {
				return err
			}
			if entry.Type()&os.ModeSymlink != 0 {
				return fmt.Errorf("symbolic links in notebook are not supported: %s", absPath)
			}
			if entry.IsDir() {
				if err := p.observe(absPath); err != nil {
					return err
				}
				if entry.Name() == "assets" {
					assetRoots = append(assetRoots, absPath)
					return filepath.SkipDir
				}
				if strings.HasPrefix(entry.Name(), ".") || entry.Name() == "storage" {
					return filepath.SkipDir
				}
				return nil
			}
			if !strings.HasSuffix(entry.Name(), ".sy") {
				return nil
			}
			if err := p.observe(absPath); err != nil {

View on GitHub (pinned to 9f775e8a12)