{"record":{"id":"fe934453f9edbb38","repo":"can1357/oh-my-pi","slug":"vault-is-disabled-enable-it-by-setting-vault","errorCode":null,"errorMessage":"vault:// is disabled. Enable it by setting `vault.enabled = true` (Settings → Tools → Obsidian Vault).","messagePattern":"vault:// is disabled\\. Enable it by setting `vault\\.enabled = true` \\(Settings → Tools → Obsidian Vault\\)\\.","errorType":"exception","errorClass":"VaultDisabledError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/vault-protocol.ts","lineNumber":424,"sourceCode":"}\n\nfunction findExistingAncestorSync(targetPath: string, rootPath: string): string {\n\tlet current = targetPath;\n\twhile (true) {\n\t\tensureWithinRoot(current, rootPath);\n\t\ttry {\n\t\t\treturn fs.realpathSync(current);\n\t\t} catch (error) {\n\t\t\tif (!isEnoent(error)) throw error;\n\t\t\tconst parent = path.dirname(current);\n\t\t\tif (parent === current) throw error;\n\t\t\tcurrent = parent;\n\t\t}\n\t}\n}\n\nexport function resolveVaultUrlToPath(input: string | InternalUrl): string {\n\tif (!isVaultEnabled()) throw new VaultDisabledError();\n\tconst parsed = parseVaultUrl(input);\n\tif (parsed.kind !== \"fs-file\" && parsed.kind !== \"fs-dir\") {\n\t\tthrow new Error(\"vault:// path resolution only supports plain filesystem paths\");\n\t}\n\n\tconst cachedRoot = getCachedVaultRoot(parsed.ref);\n\tif (!cachedRoot) {\n\t\tthrow new Error(\n\t\t\t\"vault:// path resolution requires a cached vault root; read vault:// first or use the write tool\",\n\t\t);\n\t}\n\n\tconst resolvedRoot = fs.realpathSync(cachedRoot);\n\tconst targetPath = parsed.relativePath ? path.resolve(resolvedRoot, parsed.relativePath) : resolvedRoot;\n\tensureWithinRoot(targetPath, resolvedRoot);\n\n\ttry {\n\t\tconst realTarget = fs.realpathSync(targetPath);","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/vault-protocol.ts#L406-L442","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst p = resolveVaultUrlToPath(\"vault://_/notes/idea.md\"); // throws VaultDisabledError\n// after\nif (!isVaultEnabled()) {\n  await enableVaultInSettings(); // set vault.enabled = true\n}\nconst p = resolveVaultUrlToPath(\"vault://_/notes/idea.md\");","handlingStrategy":"type-guard","validationCode":"import { isVaultEnabled } from \"./internal-urls/vault-protocol\";\nif (!isVaultEnabled()) {\n  throw new Error(\"Enable vault:// in Settings → Tools → Obsidian Vault (vault.enabled = true)\");\n}\nconst p = resolveVaultUrlToPath(url);","typeGuard":"function isVaultDisabledError(err: unknown): err is Error {\n  return err instanceof Error && err.name === \"VaultDisabledError\";\n}","tryCatchPattern":"try {\n  const p = resolveVaultUrlToPath(url);\n} catch (err) {\n  if (isVaultDisabledError(err)) {\n    ui.hint(\"vault:// is disabled — enable it in Settings → Tools → Obsidian Vault.\");\n    return null;\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["configuration","feature-flag","settings","disabled-feature"],"backgroundTag":"feature-disabled","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}