{"record":{"id":"6b9f4d1dc88e51d7","repo":"can1357/oh-my-pi","slug":"unknown-obsidian-vault-ref-vault-available","errorCode":null,"errorMessage":"Unknown Obsidian vault: ${ref.vault}\nAvailable: ${available}","messagePattern":"Unknown Obsidian vault: (.+?)\nAvailable: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/vault-protocol.ts","lineNumber":753,"sourceCode":"\t\tif (ref.active) {\n\t\t\tconst result = await this.#spawn([\"vault\", \"info\", \"path\"], context);\n\t\t\tassertCliSuccess(\"vault info path\", result);\n\t\t\tconst activePath = parseActiveVaultPath(result.stdout);\n\t\t\tif (!activePath) {\n\t\t\t\tthrow new Error(\"vault:// active vault path was empty\");\n\t\t\t}\n\t\t\tcachedActiveVaultPath = path.resolve(activePath);\n\t\t\treturn cachedActiveVaultPath;\n\t\t}\n\n\t\tif (!ref.vault) {\n\t\t\tthrow new Error(\"vault:// URL requires a vault name or '_' for the active vault\");\n\t\t}\n\t\tconst vaults = await this.#loadVaultDirectory(context);\n\t\tconst root = vaults.get(ref.vault);\n\t\tif (!root) {\n\t\t\tconst available = Array.from(vaults.keys()).sort().join(\", \") || \"none\";\n\t\t\tthrow new Error(`Unknown Obsidian vault: ${ref.vault}\\nAvailable: ${available}`);\n\t\t}\n\t\treturn path.resolve(root);\n\t}\n\n\t#vaultCliArg(ref: VaultReference): string[] {\n\t\treturn ref.forwardVault && ref.vault ? [`vault=${ref.vault}`] : [];\n\t}\n\n\tasync #listVaults(\n\t\tparsed: Extract<ParsedVaultUrl, { kind: \"list-vaults\" }>,\n\t\tcontext?: ResolveContext,\n\t): Promise<InternalResource> {\n\t\tconst vaults = await this.#loadVaultDirectory(context);\n\t\tconst entries = Array.from(vaults.keys()).sort((a, b) => a.localeCompare(b));\n\t\tconst listing =\n\t\t\tentries.length === 0\n\t\t\t\t? \"(none)\"\n\t\t\t\t: entries.map(name => `- [${name}](vault://${encodePathComponent(name)}/)`).join(\"\\n\");","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/vault-protocol.ts#L735-L771","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use one of the vault names listed in the \"Available:\" portion of the error message.","Create/open the missing vault in Obsidian so it registers, then retry.","Update saved URLs/config to the vault's current name after a rename.","Ensure the Obsidian CLI is installed and `obsidian vault list` returns your vaults."],"exampleFix":"// before\nconst url = \"vault://myvault/note.md\"; // typo: registry has \"MyVault\"\n// after\nconst url = \"vault://MyVault/note.md\";","handlingStrategy":"fallback","validationCode":"import { $ } from \"bun\";\nconst list = await $`obsidian vault list`.quiet().nothrow();\nconst names = new Set(list.text().split(/\\r?\\n/).map(l => l.split(\"\\t\")[0]).filter(Boolean));\nif (!names.has(vaultName)) throw new Error(`Unknown vault '${vaultName}'. Available: ${[...names].join(\", \") || \"none\"}`);","typeGuard":null,"tryCatchPattern":"try {\n  return await resolveInternalUrl(url);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Unknown Obsidian vault:\")) {\n    const available = err.message.split(\"Available:\")[1]?.trim() ?? \"none\";\n    // log the available vaults and abort or pick a fallback vault\n    return;\n  }\n  throw err;\n}","preventionTips":["Fetch the vault list at startup and validate configured vault names against it.","Re-validate saved vault references after Obsidian renames/moves.","Surface the \"Available:\" list from the error to users instead of failing silently."],"tags":["vault","obsidian-cli","unknown-resource"],"backgroundTag":"unknown-resource-name","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}