siyuan-note/siyuan · error
Obsidian Vault path is unsafe
Error message
Obsidian Vault path is unsafe
What it means
A sentinel base error for any Vault path deemed unsafe for import. Like the unreadable sentinel, it is wrapped with a descriptive suffix (symbolic link/reparse point, sensitive path, or workspace containment) via fmt.Errorf %w. The obsidianVaultErrorLanguage helper maps it to i18n key 338. It is the parent for errors 777, 778, and 779.
Source
Thrown at kernel/model/import_obsidian.go:232
func (err *obsidianUserError) Error() string {
return err.Cause.Error()
}
func (err *obsidianUserError) Unwrap() error {
return err.Cause
}
func newObsidianUserError(detailLanguage int, relPath string, cause error) error {
return &obsidianUserError{DetailLanguage: detailLanguage, RelPath: relPath, Cause: cause}
}
var (
obsidianTasksMu sync.Mutex
obsidianTasks = map[string]*obsidianTask{}
obsidianActive string
errObsidianVaultUnreadable = errors.New("Obsidian Vault is unreadable")
errObsidianVaultNotDirectory = errors.New("Obsidian Vault path is not a directory")
errObsidianVaultUnsafePath = errors.New("Obsidian Vault path is unsafe")
errObsidianVaultConfigMissing = errors.New("Obsidian Vault config directory is missing")
errObsidianVaultMarkdownMissing = errors.New("Obsidian Vault has no readable Markdown")
errObsidianSourceChanged = errors.New("Obsidian source file changed")
obsidianBlockIDPattern = regexp.MustCompile(`(?m)(?:^|[ \t])\^([A-Za-z0-9-]+)[ \t]*$`)
obsidianQuotePattern = regexp.MustCompile(`^((?:[ \t]*>[ \t]?)+)(.*)$`)
obsidianListItemPattern = regexp.MustCompile(`^([ \t]*(?:[-+*]|\d+[.)])[ \t]+)(.*)$`)
obsidianFootnotePattern = regexp.MustCompile(`(?m)\[\^[^\]\r\n]+\]`)
)
func StartObsidianVaultAnalysis(localPath string) (*ObsidianVaultTask, error) {
var replacedTaskID string
obsidianTasksMu.Lock()
if obsidianActive != "" {
if active := obsidianTasks[obsidianActive]; active != nil && !isObsidianTerminalState(active.State) {
if !isObsidianPreImportState(active.State) {
obsidianTasksMu.Unlock()
return nil, errors.New(Conf.Language(329))View on GitHub (pinned to 251596fc0d)
Solutions
- Use the real physical directory of the Vault, not a symlink or junction — resolve the link to its target first.
- Avoid selecting the SiYuan workspace folder or any folder that overlaps it; the Vault must be outside the workspace tree.
- Move or copy the Vault to a neutral directory if it currently sits inside or contains the workspace.
- Check the wrapped suffix to identify which safety rule fired (symlink, sensitive, or containment).
Example fix
// before: symlinked vault
localPath := "/home/user/vault-link" // -> symlink, errObsidianVaultUnsafePath
// after: resolve to real target
real, err := filepath.EvalSymlinks(localPath)
if err != nil { return err }
// pass real to startObsidianVaultAnalysis Defensive patterns
Strategy: validation
Validate before calling
// Resolve symlinks and check sensitivity/containment before calling the API
func ensureSafeVaultPath(localPath string) error {
abs, err := filepath.Abs(filepath.Clean(localPath))
if err != nil { return err }
info, err := os.Lstat(abs)
if err != nil { return err }
if info.Mode()&os.ModeSymlink != 0 { return errors.New("Vault root is a symlink; resolve it first") }
if util.IsSensitivePath(abs) { return errors.New("Vault path is sensitive") }
ws, _ := filepath.Abs(filepath.Clean(util.WorkspaceDir))
if gulu.File.IsSubPath(ws, abs) || gulu.File.IsSubPath(abs, ws) || sameObsidianPath(abs, ws) {
return errors.New("Vault overlaps the SiYuan workspace")
}
return nil
} Try / catch
if _, err := model.StartObsidianVaultAnalysis(localPath); err != nil {
if errors.Is(err, errObsidianVaultUnsafePath) {
// inspect the suffix: symlink, sensitive, or containment
return fmt.Errorf("Vault path is unsafe (%s); use a real directory outside the workspace", err)
}
} Prevention
- Resolve all symlinks in the path before importing.
- Keep the Vault outside the SiYuan workspace directory tree.
- Avoid system-sensitive paths; place Vaults under user home.
When it happens
Trigger: Calling startObsidianVaultAnalysis with a Vault root that is a symlink or Windows reparse point (line 573), a path flagged by util.IsSensitivePath (line 576), or a path that contains or is contained within the SiYuan workspace directory (line 580).
Common situations: Selecting a symlinked folder as the Vault; pointing at a system-sensitive path (e.g. /etc, a Windows system directory) that IsSensitivePath blocks; selecting the SiYuan workspace data directory itself or a parent/child of it as the Vault, which would cause recursive or destructive reads.
Related errors
- Obsidian Vault path is unsafe: Vault root is a symbolic link
- Obsidian Vault is unreadable
- Obsidian Vault path is not a directory
- Obsidian Vault config directory is missing
- Obsidian Vault has no readable Markdown
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/ef306ec13c446c9b.
Report an issue: GitHub.