{"record":{"id":"686b68872f024bea","repo":"can1357/oh-my-pi","slug":"vault-active-vault-path-was-empty","errorCode":null,"errorMessage":"vault:// active vault path was empty","messagePattern":"vault:// active vault path was empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/vault-protocol.ts","lineNumber":740,"sourceCode":"\n\tasync #loadVaultDirectory(context?: ResolveContext | WriteContext): Promise<Map<string, string>> {\n\t\tif (cachedVaultDirectory) return cachedVaultDirectory;\n\t\tconst result = await this.#spawn([\"vaults\", \"verbose\"], context);\n\t\tassertCliSuccess(\"vaults\", result);\n\t\tcachedVaultDirectory = parseVaultDirectory(result.stdout);\n\t\treturn cachedVaultDirectory;\n\t}\n\n\tasync #resolveVaultRoot(ref: VaultReference, context?: ResolveContext | WriteContext): Promise<string> {\n\t\tconst cached = getCachedVaultRoot(ref);\n\t\tif (cached) return cached;\n\n\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[] {","sourceCodeStart":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/vault-protocol.ts#L722-L758","documentation":"For vault:// URLs using the active-vault shorthand (\"_\"), the handler shells out to `obsidian vault info path` and parses the stdout for the active vault path. If parseActiveVaultPath() returns an empty string — meaning the CLI produced no recognizable path line — the handler throws this error rather than resolving to an invalid root. It indicates the Obsidian CLI answered but yielded no usable vault path.","triggerScenarios":"Resolving a vault://_/... URL when `obsidian vault info path` succeeds (exit 0) but its stdout contains no \"path\" line and either has multiple lines or is empty, so parseActiveVaultPath returns \"\".","commonSituations":"Obsidian CLI versions whose output format changed; an Obsidian installation with no vault open/focused; wrappers or plugins that add extra output around the path line.","solutions":["Open a vault in Obsidian so the CLI reports an active vault, then retry.","Run `obsidian vault info path` manually to inspect the raw output; if the format changed, upgrade the Obsidian CLI/binary to a compatible version.","Reference an explicit vault name (vault://MyVault/...) instead of the \"_\" active-vault shorthand."],"exampleFix":"// before\nconst res = await resolveInternalUrl(\"vault://_/note.md\"); // active vault unresolved\n// after\nconst res = await resolveInternalUrl(\"vault://MyVault/note.md\"); // explicit vault","handlingStrategy":"try-catch","validationCode":"import { $ } from \"bun\";\nconst info = await $`obsidian vault info path`.quiet().nothrow();\nconst usable = info.exitCode === 0 && info.text().trim().length > 0;\nif (!usable) throw new Error(\"Obsidian CLI reports no active vault; open one or name the vault explicitly\");","typeGuard":null,"tryCatchPattern":"try {\n  const root = await resolveVaultRoot(ref, ctx);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"active vault path was empty\")) {\n    // fall back to an explicit vault name or prompt the user to open a vault\n    return;\n  }\n  throw err;\n}","preventionTips":["Prefer explicit vault names over the \"_\" active-vault shorthand in automation.","Verify `obsidian vault info path` returns a single path line before relying on it.","Keep the Obsidian CLI current; its output format drives the parser."],"tags":["vault","obsidian-cli","parsing"],"backgroundTag":"cli-output-parse-failure","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}