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
- Find the offending symlink at the reported absolute path and remove it, replacing it with a real copy of the target if needed.
- Re-run the relink with dryRun=true to confirm no other symlinks remain (the scan stops at the first one).
- Exclude symlinked content from the notebook, or move shared assets into a location the scan supports.
- 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
- Do not symlink files or folders into data/notebooks
- Avoid sync tools that materialize symlinks in the workspace
- Scan the notebook for symlinks before running relink operations
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
- asset must be a regular file
- asset path contains an unresolved symbolic link
- asset path resolves outside notebook assets directory
- attribute view definition is not a regular file
- encrypted document is a symbolic link
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)