siyuan-note/siyuan · error
Obsidian Vault path is unsafe: Vault root and SiYuan workspa
Error message
Obsidian Vault path is unsafe: Vault root and SiYuan workspace contain each other
What it means
A wrapped variant of errObsidianVaultUnsafePath (line 579-581): returned when the Vault root is the same as, a parent of, or a child of the SiYuan workspace directory. The check uses sameObsidianPath and gulu.File.IsSubPath in both directions to prevent recursive or destructive directory relationships. Importing a Vault that overlaps the workspace would cause SiYuan to scan its own data directory, leading to infinite recursion or data corruption. The error wraps the unsafe sentinel with ': Vault root and SiYuan workspace contain each other'.
Source
Thrown at kernel/model/import_obsidian.go:581
if err != nil {
return "", fmt.Errorf("%w: normalize Vault path: %v", errObsidianVaultUnreadable, err)
}
info, err := os.Lstat(abs)
if err != nil {
return "", fmt.Errorf("%w: read Vault root: %v", errObsidianVaultUnreadable, err)
}
if !info.IsDir() {
return "", errObsidianVaultNotDirectory
}
if info.Mode()&os.ModeSymlink != 0 || isObsidianResolvedLink(abs) {
return "", fmt.Errorf("%w: Vault root is a symbolic link or reparse point", errObsidianVaultUnsafePath)
}
if util.IsSensitivePath(abs) {
return "", fmt.Errorf("%w: selected Vault path is sensitive", errObsidianVaultUnsafePath)
}
workspace, _ := filepath.Abs(filepath.Clean(util.WorkspaceDir))
if sameObsidianPath(abs, workspace) || gulu.File.IsSubPath(workspace, abs) || gulu.File.IsSubPath(abs, workspace) {
return "", fmt.Errorf("%w: Vault root and SiYuan workspace contain each other", errObsidianVaultUnsafePath)
}
configPath := filepath.Join(abs, ".obsidian")
configInfo, statErr := os.Lstat(configPath)
if statErr != nil {
if os.IsNotExist(statErr) {
return "", errObsidianVaultConfigMissing
}
return "", fmt.Errorf("%w: read Vault config directory: %v", errObsidianVaultUnreadable, statErr)
}
if !configInfo.IsDir() || configInfo.Mode()&os.ModeSymlink != 0 || isObsidianResolvedLink(configPath) {
return "", errObsidianVaultConfigMissing
}
return abs, nil
}
func scanObsidianVaultFiles(ctx context.Context, vault *obsidianVaultContext, relDir, absDir string) error {
if err := ctx.Err(); err != nil {
return errView on GitHub (pinned to 251596fc0d)
Solutions
- Move the Vault to a directory completely outside the SiYuan workspace tree.
- If the workspace was set inside the Vault, change the SiYuan workspace to a different location.
- Use a copy of the Vault in a neutral directory (e.g. /tmp or ~/Imports) for import.
- Confirm the two paths share no ancestor/descendant relationship before importing.
Example fix
// before: vault is inside the workspace // workspace = /home/user/SiYuan/data // vault = /home/user/SiYuan/data/MyVault // -> "Obsidian Vault path is unsafe: Vault root and SiYuan workspace contain each other" // after: vault outside workspace // vault = /home/user/ObsidianVaults/MyVault
Defensive patterns
Strategy: validation
Validate before calling
// Ensure no overlap between Vault root and workspace
abs, _ := filepath.Abs(filepath.Clean(localPath))
ws, _ := filepath.Abs(filepath.Clean(util.WorkspaceDir))
if abs == ws || gulu.File.IsSubPath(ws, abs) || gulu.File.IsSubPath(abs, ws) {
return errors.New("Vault path overlaps the SiYuan workspace; choose a separate directory")
} Try / catch
if _, err := model.StartObsidianVaultAnalysis(localPath); err != nil {
if errors.Is(err, errObsidianVaultUnsafePath) && strings.Contains(err.Error(), "contain each other") {
return errors.New("the Vault overlaps the SiYuan workspace; move it to a separate directory")
}
} Prevention
- Keep the Vault completely outside the SiYuan workspace directory tree.
- Do not set the SiYuan workspace to the Vault's parent.
- Copy the Vault to a neutral location if it currently overlaps the workspace.
When it happens
Trigger: POST /api/import/startObsidianVaultAnalysis where abs == workspace, workspace is under abs (Vault is a parent of workspace), or abs is under workspace (Vault is inside the SiYuan data dir). Any of the three IsSubPath/sameObsidianPath checks at line 580 returns true.
Common situations: User placed the Obsidian Vault inside the SiYuan workspace/data folder; the workspace was set to the Vault's parent; the user confused the two directories and selected the workspace itself as the Vault; a default workspace path happens to contain the Vault.
Related errors
- Obsidian Vault path is unsafe
- Obsidian Vault path is unsafe: Vault root is a symbolic link
- Obsidian Vault path is unsafe: selected Vault path is sensit
- invalid import token
- import path is not sub path of import dir
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/f6d36f36c5dd735e.
Report an issue: GitHub.