siyuan-note/siyuan · error

%w: path is empty

Error message

%w: path is empty

What it means

validateObsidianVaultRoot rejects an empty/whitespace-only Vault local path by wrapping errObsidianVaultUnreadable with 'path is empty'. The caller must supply a concrete filesystem path to the Obsidian vault directory before analysis can begin.

Source

Thrown at kernel/model/import_obsidian.go:560

			}
			ret.Analysis.Warnings = append(ret.Analysis.Warnings, asset.Source.RelPath)
			continue
		}
		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)
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Pass the absolute path of the Obsidian vault directory (the folder containing .obsidian) in the request
  2. Validate the path is non-empty on the client before invoking the API
  3. If path comes from settings/env, check the value exists before starting the import
  4. Re-open the vault picker in the UI and confirm the selection

Example fix

// before
analyzeObsidianVault("") // throws: path is empty
// after
if vaultPath == "" {
    return errors.New("vault path is required")
}
analyzeObsidianVault(vaultPath)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(vaultPath) == "" {
    return errors.New("vault path is required")
}

Type guard

null

Try / catch

_, err := AnalyzeObsidianVault(vaultPath)
if err != nil && strings.Contains(err.Error(), "path is empty") {
    promptUserToPickVaultFolder()
}

Prevention

When it happens

Trigger: Calling the Obsidian analyze/import API with localPath == "" or only whitespace at kernel/model/import_obsidian.go:560 — e.g. the folder-picker returned nothing or a config field was never filled in.

Common situations: Frontend sends an unset path because the user skipped choosing a vault; a saved settings file lost the vaultPath key; automation passed an env variable that is empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/ddb61d735ffe425b. Report an issue: GitHub.