can1357/oh-my-pi · error

Unknown Obsidian vault: ${ref.vault} Available: ${available}

Error message

Unknown Obsidian vault: ${ref.vault}
Available: ${available}

What it means

After loading the vault directory (via the Obsidian CLI), resolveVaultRoot looks up ref.vault in the registry. If the named vault is not registered, the handler throws this error listing all known vault names (or "none" if the registry is empty). It means the URL is well-formed but names a vault Obsidian does not know.

Source

Thrown at packages/coding-agent/src/internal-urls/vault-protocol.ts:753

		if (ref.active) {
			const result = await this.#spawn(["vault", "info", "path"], context);
			assertCliSuccess("vault info path", result);
			const activePath = parseActiveVaultPath(result.stdout);
			if (!activePath) {
				throw new Error("vault:// active vault path was empty");
			}
			cachedActiveVaultPath = path.resolve(activePath);
			return cachedActiveVaultPath;
		}

		if (!ref.vault) {
			throw new Error("vault:// URL requires a vault name or '_' for the active vault");
		}
		const vaults = await this.#loadVaultDirectory(context);
		const root = vaults.get(ref.vault);
		if (!root) {
			const available = Array.from(vaults.keys()).sort().join(", ") || "none";
			throw new Error(`Unknown Obsidian vault: ${ref.vault}\nAvailable: ${available}`);
		}
		return path.resolve(root);
	}

	#vaultCliArg(ref: VaultReference): string[] {
		return ref.forwardVault && ref.vault ? [`vault=${ref.vault}`] : [];
	}

	async #listVaults(
		parsed: Extract<ParsedVaultUrl, { kind: "list-vaults" }>,
		context?: ResolveContext,
	): Promise<InternalResource> {
		const vaults = await this.#loadVaultDirectory(context);
		const entries = Array.from(vaults.keys()).sort((a, b) => a.localeCompare(b));
		const listing =
			entries.length === 0
				? "(none)"
				: entries.map(name => `- [${name}](vault://${encodePathComponent(name)}/)`).join("\n");

View on GitHub (pinned to 9690622007)

Solutions

  1. Use one of the vault names listed in the "Available:" portion of the error message.
  2. Create/open the missing vault in Obsidian so it registers, then retry.
  3. Update saved URLs/config to the vault's current name after a rename.
  4. Ensure the Obsidian CLI is installed and `obsidian vault list` returns your vaults.

Example fix

// before
const url = "vault://myvault/note.md"; // typo: registry has "MyVault"
// after
const url = "vault://MyVault/note.md";
Defensive patterns

Strategy: fallback

Validate before calling

import { $ } from "bun";
const list = await $`obsidian vault list`.quiet().nothrow();
const names = new Set(list.text().split(/\r?\n/).map(l => l.split("\t")[0]).filter(Boolean));
if (!names.has(vaultName)) throw new Error(`Unknown vault '${vaultName}'. Available: ${[...names].join(", ") || "none"}`);

Try / catch

try {
  return await resolveInternalUrl(url);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Unknown Obsidian vault:")) {
    const available = err.message.split("Available:")[1]?.trim() ?? "none";
    // log the available vaults and abort or pick a fallback vault
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Resolving vault://SomeVault/... where "SomeVault" is not among the names returned by the vault directory (e.g. `obsidian vault list`), including after a vault was renamed, deleted, or never created.

Common situations: Typo'd vault names; vaults renamed in Obsidian while saved URLs/config still use the old name; syncing configs across machines where the vault registry differs; Obsidian not installed so the registry is empty.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/6b9f4d1dc88e51d7. Report an issue: GitHub.