can1357/oh-my-pi · error · VaultDisabledError
vault:// is disabled. Enable it by setting `vault.enabled =
Error message
vault:// is disabled. Enable it by setting `vault.enabled = true` (Settings → Tools → Obsidian Vault).
What it means
Both `resolveVaultUrlToPath` and `VaultProtocolHandler.resolve` begin by checking `isVaultEnabled()`, which reads `vault.enabled` from settings (falling back to the schema default when settings are not initialized). If the feature flag is off, a `VaultDisabledError` with this exact message is thrown before any URL parsing. The vault:// protocol is opt-in.
Source
Thrown at packages/coding-agent/src/internal-urls/vault-protocol.ts:424
}
function findExistingAncestorSync(targetPath: string, rootPath: string): string {
let current = targetPath;
while (true) {
ensureWithinRoot(current, rootPath);
try {
return fs.realpathSync(current);
} catch (error) {
if (!isEnoent(error)) throw error;
const parent = path.dirname(current);
if (parent === current) throw error;
current = parent;
}
}
}
export function resolveVaultUrlToPath(input: string | InternalUrl): string {
if (!isVaultEnabled()) throw new VaultDisabledError();
const parsed = parseVaultUrl(input);
if (parsed.kind !== "fs-file" && parsed.kind !== "fs-dir") {
throw new Error("vault:// path resolution only supports plain filesystem paths");
}
const cachedRoot = getCachedVaultRoot(parsed.ref);
if (!cachedRoot) {
throw new Error(
"vault:// path resolution requires a cached vault root; read vault:// first or use the write tool",
);
}
const resolvedRoot = fs.realpathSync(cachedRoot);
const targetPath = parsed.relativePath ? path.resolve(resolvedRoot, parsed.relativePath) : resolvedRoot;
ensureWithinRoot(targetPath, resolvedRoot);
try {
const realTarget = fs.realpathSync(targetPath);View on GitHub (pinned to 9690622007)
Solutions
- Enable the feature: set `vault.enabled = true` in settings (Settings → Tools → Obsidian Vault in the UI).
- Catch `VaultDisabledError` (check `error.name === "VaultDisabledError"`) and surface the enablement instructions to the user.
- In tests/SDK code, initialize settings with vault.enabled = true before resolving vault:// URLs, or use VaultProtocolHandler test hooks.
Example fix
// before
const p = resolveVaultUrlToPath("vault://_/notes/idea.md"); // throws VaultDisabledError
// after
if (!isVaultEnabled()) {
await enableVaultInSettings(); // set vault.enabled = true
}
const p = resolveVaultUrlToPath("vault://_/notes/idea.md"); Defensive patterns
Strategy: type-guard
Validate before calling
import { isVaultEnabled } from "./internal-urls/vault-protocol";
if (!isVaultEnabled()) {
throw new Error("Enable vault:// in Settings → Tools → Obsidian Vault (vault.enabled = true)");
}
const p = resolveVaultUrlToPath(url); Type guard
function isVaultDisabledError(err: unknown): err is Error {
return err instanceof Error && err.name === "VaultDisabledError";
} Try / catch
try {
const p = resolveVaultUrlToPath(url);
} catch (err) {
if (isVaultDisabledError(err)) {
ui.hint("vault:// is disabled — enable it in Settings → Tools → Obsidian Vault.");
return null;
}
throw err;
} Prevention
- Gate vault:// code paths behind isVaultEnabled()/hasObsidian() checks
- In tests and SDK embedding, initialize settings with vault.enabled = true first
- Treat vault:// links found in notes as optional content when the flag is off
- Document the opt-in requirement wherever vault:// URLs are surfaced to users
When it happens
Trigger: Calling resolveVaultUrlToPath() or handler.resolve() while the active settings profile has `vault.enabled = false` (or unset and the schema default is false), or in tests/SDK embedding where Settings.init has not run and the default disables vault.
Common situations: Fresh installs where the user never enabled the Obsidian integration; resolving vault:// links from notes on a machine with a different settings profile; CI/test environments without initialized settings.
Related errors
- Unknown protocol: memory://
- Security is disabled; enable security.enabled before plannin
- Security is disabled; enable security.enabled before startin
- Vibe tools are unavailable in this session.
- Agent "${agentName}" is disabled in settings. Enable it via
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/fe934453f9edbb38.
Report an issue: GitHub.