siyuan-note/siyuan · error · errObsidianVaultUnreadable
%w: normalize Vault path: %v
Error message
%w: normalize Vault path: %v
What it means
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>'.
Source
Thrown at kernel/model/import_obsidian.go:564
ret.ImportAssets[key] = asset
ret.Analysis.ImportableAssetCount++
ret.Analysis.ImportableAssetSize += asset.Source.Size
}
ret.Analysis.UnreferencedFileCount = len(ret.ImportAssets) - len(ret.ReferencedAssets)
if ret.Analysis.UnreferencedFileCount < 0 {
ret.Analysis.UnreferencedFileCount = 0
}
progress(100, "Analysis completed")
return ret, nil
}
func validateObsidianVaultRoot(localPath string) (string, error) {
if strings.TrimSpace(localPath) == "" {
return "", fmt.Errorf("%w: path is empty", errObsidianVaultUnreadable)
}
abs, err := filepath.Abs(filepath.Clean(localPath))
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)
}View on GitHub (pinned to 8641553a1f)
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)
Example fix
// before
analyzeObsidianVault("../my/vault") // relative, fails if cwd gone
// after
analyzeObsidianVault("/Users/me/Documents/my-vault") Defensive patterns
Strategy: validation
Validate before calling
abs, err := filepath.Abs(vaultPath)
if err != nil { return err }
if _, err := os.Stat(abs); err != nil { return err } Type guard
null
Try / catch
_, err := AnalyzeObsidianVault(vaultPath)
if err != nil && strings.Contains(err.Error(), "normalize Vault path") {
// pass absolute path and restart kernel from a valid cwd
AnalyzeObsidianVault(filepath.Join(wsDir, vaultPath))
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- read referenced attachment [%s]: %w
- %w: read Vault root: %v
- %w: Vault root and SiYuan workspace contain each other
- %w: read Vault config directory: %v
- read Vault directory [%s]: %w
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/791d9a81e34009c2.
Report an issue: GitHub.