# Vault Selection Order for claude-obsidian: How the Tool Locates Your Notes

> Understand the claude-obsidian vault selection order. Discover how the tool prioritizes paths through CLI arguments environment variables workspace config and more for efficient note access.

- Repository: [Agrici.Daniel/claude-obsidian](https://github.com/AgriciDaniel/claude-obsidian)
- Tags: how-to-guide
- Published: 2026-08-29

---

**The vault selection order for claude-obsidian follows a strict five-step precedence chain: explicit CLI argument → environment variable → workspace config file → current directory discovery → plugin-root safeguard, as implemented in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py).**

Understanding the vault selection order for claude-obsidian is essential when working across multiple Obsidian vaults or automated environments. The tool implements a deterministic resolution algorithm in the **AgriciDaniel/claude-obsidian** repository that searches for your notes directory through a cascading priority system. This guide explains the exact precedence chain used by the `resolve_vault_root()` function and how each discovery method functions in practice.

## The Five-Level Precedence Chain

The vault resolution logic lives in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py) and evaluates candidates in the following strict order:

### 1. Explicit `--vault` CLI Argument

The highest priority source is the `--vault` command-line flag. When provided, this value is taken immediately as the vault root without further discovery.

- **Source identifier:** `"explicit"`
- **Implementation:** Lines 81–84 in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py)
- **Behavior:** Overrides all other configuration methods

### 2. `CLAUDE_OBSIDIAN_VAULT` Environment Variable

If no CLI argument is present, the tool checks for the `CLAUDE_OBSIDIAN_VAULT` environment variable. When set, its value becomes the vault path.

- **Source identifier:** `"environment"`
- **Implementation:** Lines 84–87 in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py)
- **Use case:** CI/CD pipelines and shell scripts where flags are impractical

### 3. Nearest Workspace Configuration File

The third priority searches upward from the current working directory for a [`.claude-obsidian.json`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/.claude-obsidian.json) file. If found, the containing directory is treated as the vault root.

- **Source identifier:** `"workspace-config"`
- **Implementation:** Lines 88–92 in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py) via `_find_workspace_config()`
- **Behavior:** Enables per-project vault pinning without environment variables

### 4. Current Working Directory Discovery (CWD)

When no config file exists, the algorithm walks up the directory tree from the current location looking for a vault containing the required layout (such as a `wiki/` folder). This implicit discovery is called **cwd-discovery**.

- **Source identifier:** `"cwd-discovery"`
- **Implementation:** Lines 96–100 in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py) via `_nearest_vault()`
- **Limitation:** Excludes the plugin installation directory (see safeguard below)

### 5. Plugin-Root Exclusion Safeguard

The final step is a security guard rather than a selection source. If directory discovery resolves to the plugin's own installation directory (`PLUGIN_ROOT`), the tool raises a `VaultSelectionError` unless the caller explicitly sets `allow_plugin_root=True`.

- **Purpose:** Prevents accidental operations on the tool's source code
- **Implementation:** Lines 97–101 in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py)
- **Error reference:** Exit code 2 defined in [`claude_obsidian/legacy_lock.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/legacy_lock.py)

## Implementation Details in `resolve_vault_root()`

After selecting a candidate path through the precedence chain, the `resolve_vault_root()` function performs validation via `validate_vault_root()` and returns a **`VaultSelection`** dataclass containing:

- **root:** The resolved filesystem path to the vault
- **source:** A string indicating which precedence level succeeded (`"explicit"`, `"environment"`, `"workspace-config"`, or `"cwd-discovery"`)
- **legacy:** A boolean flag set to `True` if the vault lacks a [`.claude-obsidian.json`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/.claude-obsidian.json) configuration file

The CLI entry point in [`claude_obsidian/cli.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/cli.py) calls this logic through `_selection()` to determine which vault to operate on for every command.

## Practical CLI Examples

Override all other methods by specifying the path directly:

```bash
python -m claude_obsidian --vault /my/custom/vault doctor

# Returns: selection.source == "explicit"

```

Use environment variables for automation workflows:

```bash
export CLAUDE_OBSIDIAN_VAULT=/my/env/vault
python -m claude_obsidian doctor

# Returns: selection.source == "environment"

```

Rely on workspace configuration discovery:

```bash

# From a directory containing or nested within a .claude-obsidian.json file:

python -m claude_obsidian doctor

# Returns: selection.source == "workspace-config"

```

Trigger implicit discovery when no config exists:

```bash

# Tool walks upward until finding a valid vault layout

python -m claude_obsidian doctor

# Returns: selection.source == "cwd-discovery"

```

## Error Handling and Legacy Detection

If the discovery algorithm fails to locate a valid vault, or if it detects the plugin root without explicit permission, it raises **`VaultSelectionError`** with specific exit codes (defined in [`claude_obsidian/legacy_lock.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/legacy_lock.py)). Legacy vaults—those selected via cwd-discovery without a workspace config file—are flagged to indicate they may not support newer features requiring explicit configuration.

## Summary

- **Primary resolution:** `resolve_vault_root()` in [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py) implements a deterministic five-step precedence chain
- **Priority order:** CLI flag → Environment variable → [`.claude-obsidian.json`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/.claude-obsidian.json) → CWD upward search → Plugin-root guard
- **Safety mechanism:** The plugin installation directory is excluded from automatic discovery to prevent self-modification
- **Return value:** A `VaultSelection` object containing the path, source method, and legacy status
- **CLI integration:** [`claude_obsidian/cli.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/cli.py) consumes this logic for all vault-aware commands

## Frequently Asked Questions

### What happens if no vault is specified and no config file exists?

The tool enters **cwd-discovery mode**, traversing upward from the current directory until it finds a directory containing valid vault indicators (such as a `wiki/` folder). If no valid vault is found before reaching the filesystem root, a `VaultSelectionError` is raised.

### Why does claude-obsidian reject the plugin installation directory?

To prevent accidental file operations on its own source code, the tool explicitly excludes `PLUGIN_ROOT` from implicit discovery. If the upward search resolves to the installation directory, the code raises a `VaultSelectionError` unless you explicitly pass `allow_plugin_root=True` to the underlying function.

### How can I verify which vault selection method was used?

The `resolve_vault_root()` function returns a `VaultSelection` object with a **`source`** attribute. This string indicates whether the vault was resolved via `"explicit"` (CLI flag), `"environment"` (env var), `"workspace-config"` (JSON file), or `"cwd-discovery"` (implicit search).

### What marks a vault as "legacy" in the selection result?

A vault is flagged as **legacy** if it lacks a [`.claude-obsidian.json`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/.claude-obsidian.json) workspace configuration file. This typically occurs when the vault is discovered through cwd-discovery rather than explicit configuration, indicating it may predate newer workspace-aware features in the toolchain.