can1357/oh-my-pi · error

vault:// URL requires a vault name or '_' for the active vau

Error message

vault:// URL requires a vault name or '_' for the active vault

What it means

A vault:// URL must name a vault (vault://<name>/...) or use "_" for the active vault. When the parsed VaultReference has neither — no vault component and not the active-vault form — resolveVaultRoot throws this error before consulting the vault directory. It is a strict URL-shape validation on the host portion of the URL.

Source

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

	}

	async #resolveVaultRoot(ref: VaultReference, context?: ResolveContext | WriteContext): Promise<string> {
		const cached = getCachedVaultRoot(ref);
		if (cached) return cached;

		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> {

View on GitHub (pinned to 9690622007)

Solutions

  1. Include a vault name in the URL host: vault://<vault-name>/path/to/file.md.
  2. Use the active-vault shorthand "_" if you mean the currently open vault: vault://_/path/to/file.md.
  3. Validate the URL with parseVaultUrl() before passing it to the handler.

Example fix

// before
const url = `vault://${vaultName}/note.md`; // vaultName was empty -> throws
// after
const url = vaultName ? `vault://${vaultName}/note.md` : "vault://_/note.md";
Defensive patterns

Strategy: validation

Validate before calling

const host = new URL(url.href).host; // or parse the vault segment
if (url.href.startsWith("vault://") && host !== "_" && host.length === 0) {
  throw new Error("vault:// URL needs a vault name or '_' for the active vault");
}

Type guard

function hasVaultComponent(href: string): boolean {
  const m = /^vault:\/\/([^/]+)/.exec(href);
  return !!m && m[1].length > 0;
}

Try / catch

try {
  return await resolveInternalUrl(url);
} catch (err) {
  if (err instanceof Error && err.message.includes("requires a vault name or '_'") && activeVault) {
    return resolveInternalUrl(url.replace("vault://", `vault://${activeVault}/`));
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling resolve/write with a malformed vault:// URL whose host/vault part is empty and not "_", e.g. "vault:///note.md" or "vault://" followed only by a path.

Common situations: String-built URLs where the vault segment was dropped by path-joining code; templates with an unfilled vault-name variable; trimming that consumed the vault segment.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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