{"record":{"id":"bfa6f13e3553e944","repo":"siyuan-note/siyuan","slug":"obsidian-vault-path-is-unsafe-selected-vault-path","errorCode":null,"errorMessage":"Obsidian Vault path is unsafe: selected Vault path is sensitive","messagePattern":"Obsidian Vault path is unsafe: selected Vault path is sensitive","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/import_obsidian.go","lineNumber":577,"sourceCode":"\tif strings.TrimSpace(localPath) == \"\" {\n\t\treturn \"\", fmt.Errorf(\"%w: path is empty\", errObsidianVaultUnreadable)\n\t}\n\tabs, err := filepath.Abs(filepath.Clean(localPath))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"%w: normalize Vault path: %v\", errObsidianVaultUnreadable, err)\n\t}\n\tinfo, err := os.Lstat(abs)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"%w: read Vault root: %v\", errObsidianVaultUnreadable, err)\n\t}\n\tif !info.IsDir() {\n\t\treturn \"\", errObsidianVaultNotDirectory\n\t}\n\tif info.Mode()&os.ModeSymlink != 0 || isObsidianResolvedLink(abs) {\n\t\treturn \"\", fmt.Errorf(\"%w: Vault root is a symbolic link or reparse point\", errObsidianVaultUnsafePath)\n\t}\n\tif util.IsSensitivePath(abs) {\n\t\treturn \"\", fmt.Errorf(\"%w: selected Vault path is sensitive\", errObsidianVaultUnsafePath)\n\t}\n\tworkspace, _ := filepath.Abs(filepath.Clean(util.WorkspaceDir))\n\tif sameObsidianPath(abs, workspace) || gulu.File.IsSubPath(workspace, abs) || gulu.File.IsSubPath(abs, workspace) {\n\t\treturn \"\", fmt.Errorf(\"%w: Vault root and SiYuan workspace contain each other\", errObsidianVaultUnsafePath)\n\t}\n\tconfigPath := filepath.Join(abs, \".obsidian\")\n\tconfigInfo, statErr := os.Lstat(configPath)\n\tif statErr != nil {\n\t\tif os.IsNotExist(statErr) {\n\t\t\treturn \"\", errObsidianVaultConfigMissing\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"%w: read Vault config directory: %v\", errObsidianVaultUnreadable, statErr)\n\t}\n\tif !configInfo.IsDir() || configInfo.Mode()&os.ModeSymlink != 0 || isObsidianResolvedLink(configPath) {\n\t\treturn \"\", errObsidianVaultConfigMissing\n\t}\n\treturn abs, nil\n}","sourceCodeStart":559,"sourceCodeEnd":595,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/import_obsidian.go#L559-L595","documentation":"A wrapped variant of errObsidianVaultUnsafePath (line 576-577): returned when util.IsSensitivePath(abs) flags the resolved Vault root as a sensitive/system path. IsSensitivePath blocks OS-critical directories (e.g. /, /etc, /usr, Windows system directories) to prevent accidental or malicious reads of system files during the recursive Vault scan. The error wraps the unsafe sentinel with ': selected Vault path is sensitive'.","triggerScenarios":"POST /api/import/startObsidianVaultAnalysis with a localPath resolving to a path IsSensitivePath considers dangerous — a filesystem root, a system directory, or a path on IsSensitivePath's blocklist.","commonSituations":"User accidentally selects the filesystem root (/) or a system directory as the Vault; a path like /etc or C:\\Windows is chosen; the Vault happens to live inside a directory IsSensitivePath flags.","solutions":["Select a user-data directory for the Vault (e.g. under the home directory), not a system root or OS folder.","If the Vault legitimately resides under a flagged path, move or copy it to a neutral location like ~/Vaults.","Check IsSensitivePath's blocklist to understand which ancestor path triggered the flag and avoid it."],"exampleFix":"// before\nlocalPath := \"/\" // or C:\\\n// -> \"Obsidian Vault path is unsafe: selected Vault path is sensitive\"\n\n// after\nlocalPath := \"/home/user/ObsidianVaults/MyVault\"","handlingStrategy":"validation","validationCode":"// Reject sensitive system paths before calling the API\nif util.IsSensitivePath(abs) {\n    return errors.New(\"selected path is a sensitive system directory; choose a user-data folder\")\n}","typeGuard":null,"tryCatchPattern":"if _, err := model.StartObsidianVaultAnalysis(localPath); err != nil {\n    if errors.Is(err, errObsidianVaultUnsafePath) && strings.Contains(err.Error(), \"sensitive\") {\n        return errors.New(\"the selected path is a sensitive system directory; move the Vault to a user folder\")\n    }\n}","preventionTips":["Place Vaults under the user home directory, never at filesystem roots or system folders.","Run a sensitivity check on the client before submitting the path."],"tags":["obsidian","import","security","validation","sensitive-path"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}