{"record":{"id":"791d9a81e34009c2","repo":"siyuan-note/siyuan","slug":"w-normalize-vault-path-v","errorCode":null,"errorMessage":"%w: normalize Vault path: %v","messagePattern":"%w: normalize Vault path: (.+?)","errorType":"error_code","errorClass":"errObsidianVaultUnreadable","httpStatus":null,"severity":"error","filePath":"kernel/model/import_obsidian.go","lineNumber":564,"sourceCode":"\t\tret.ImportAssets[key] = asset\n\t\tret.Analysis.ImportableAssetCount++\n\t\tret.Analysis.ImportableAssetSize += asset.Source.Size\n\t}\n\tret.Analysis.UnreferencedFileCount = len(ret.ImportAssets) - len(ret.ReferencedAssets)\n\tif ret.Analysis.UnreferencedFileCount < 0 {\n\t\tret.Analysis.UnreferencedFileCount = 0\n\t}\n\tprogress(100, \"Analysis completed\")\n\treturn ret, nil\n}\n\nfunc validateObsidianVaultRoot(localPath string) (string, error) {\n\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}","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/import_obsidian.go#L546-L582","documentation":"The provided Vault path could not be converted to an absolute, cleaned path: filepath.Abs/Clean failed (rare, usually working-directory or OS-level problems). The kernel wraps errObsidianVaultUnreadable with 'normalize Vault path: <detail>'.","triggerScenarios":"filepath.Abs(filepath.Clean(localPath)) returning an error in validateObsidianVaultRoot (kernel/model/import_obsidian.go:564), typically because the process working directory could not be determined (getwd failure) while localPath is relative.","commonSituations":"Kernel started from a deleted working directory; relative vault path supplied while the process cwd is gone; exotic characters/length causing OS path handling failures on some platforms.","solutions":["Pass an absolute vault path so filepath.Abs does not need the process working directory","Verify the kernel's working directory still exists and the workspace is valid; restart the kernel if it was started from a deleted dir","Check the error detail appended to the message for the underlying OS cause","Re-run after fixing the environment (cwd, permissions)"],"exampleFix":"// before\nanalyzeObsidianVault(\"../my/vault\") // relative, fails if cwd gone\n// after\nanalyzeObsidianVault(\"/Users/me/Documents/my-vault\")","handlingStrategy":"validation","validationCode":"abs, err := filepath.Abs(vaultPath)\nif err != nil { return err }\nif _, err := os.Stat(abs); err != nil { return err }","typeGuard":"null","tryCatchPattern":"_, err := AnalyzeObsidianVault(vaultPath)\nif err != nil && strings.Contains(err.Error(), \"normalize Vault path\") {\n    // pass absolute path and restart kernel from a valid cwd\n    AnalyzeObsidianVault(filepath.Join(wsDir, vaultPath))\n}","preventionTips":["Always pass absolute vault paths","Ensure the kernel process is started from an existing working directory","Quote/limit path length to avoid OS path-length issues"],"tags":["obsidian-import","path-normalization","filesystem","filepath"],"backgroundTag":"invalid-argument-value","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}