can1357/oh-my-pi · error

Unsupported vault:// file op: ${rawOp}

Error message

Unsupported vault:// file op: ${rawOp}

What it means

When a vault:// URL includes a file path plus an `op` query parameter, `parseVaultOp` only accepts the whitelisted file operations (outline, backlinks, links, tags, properties, tasks, wordcount, history, base). Any other `op` value with a path present is rejected with this error. The whitelist is intentional: file ops map one-to-one to Obsidian CLI subcommands.

Source

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

function makeVaultReference(host: string): VaultReference {
	if (!host || host === "_") {
		return { vault: null, active: true, forwardVault: false, display: "_" };
	}
	return { vault: host, active: false, forwardVault: true, display: host };
}

function isFileOp(rawOp: string): rawOp is FileOp {
	return FILE_OPS[rawOp as FileOp] === true;
}

function isVaultOp(rawOp: string): rawOp is VaultOp {
	return VAULT_OPS[rawOp as VaultOp] === true;
}

function parseVaultOp(rawOp: string, hasFilePath: boolean): FileOp | VaultOp {
	if (hasFilePath) {
		if (!isFileOp(rawOp)) {
			throw new Error(`Unsupported vault:// file op: ${rawOp}`);
		}
		return rawOp;
	}
	if (!isVaultOp(rawOp)) {
		throw new Error(`Unsupported vault:// vault op: ${rawOp}`);
	}
	return rawOp;
}

export function parseVaultUrl(input: string | InternalUrl): ParsedVaultUrl {
	const url = typeof input === "string" ? parseInternalUrl(input) : input;
	const host = url.rawHost || url.hostname;
	const params = paramsFromUrl(url);
	const rawOp = typeof params.op === "string" ? params.op : undefined;
	const { rawPathname, relativePath, hasPath, isDirectory } = decodeVaultPath(url);

	if (!host && !hasPath && !rawOp) {
		return { kind: "list-vaults", url: url.href, params };

View on GitHub (pinned to 9690622007)

Solutions

  1. Use one of the supported file ops: outline, backlinks, links, tags, properties, tasks, wordcount, history, base.
  2. If you intended a vault-wide op (search, daily, orphans, unresolved, deadends, bases, bookmarks, recents, templates, aliases, property), remove the file path from the URL.
  3. Fix casing/typos — op matching is exact and case-sensitive.
  4. If the op genuinely exists in the Obsidian CLI, add it to FILE_OPS in vault-protocol.ts.

Example fix

// before
const url = "vault://_/notes/idea.md?op=search&q=test"; // search is not a file op
// after
const url = "vault://_/?op=search&q=test"; // vault-wide search, no path
// or per-file:
const url2 = "vault://_/notes/idea.md?op=backlinks";
Defensive patterns

Strategy: validation

Validate before calling

const FILE_OPS = ["outline","backlinks","links","tags","properties","tasks","wordcount","history","base"];
function isValidFileOp(op: string): boolean { return FILE_OPS.includes(op); }
// check isValidFileOp(op) before appending ?op= to a path-bearing vault:// URL

Type guard

function isFileOpOp(op: string): op is "outline"|"backlinks"|"links"|"tags"|"properties"|"tasks"|"wordcount"|"history"|"base" {
  return ["outline","backlinks","links","tags","properties","tasks","wordcount","history","base"].includes(op);
}

Try / catch

try {
  const res = await handler.resolve(parseInternalUrl(url));
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Unsupported vault:// file op:")) {
    // fall back to reading the file itself or a supported op
  } else throw err;
}

Prevention

When it happens

Trigger: `vault://_/notes/foo.md?op=summarize`, `?op=search` (search is a vault op, not a file op), `?op=Outline` (case-sensitive), or a typo like `?op=backlink` while the URL has a non-empty path.

Common situations: Assuming every vault op also works per-file (e.g. `search` with a path); typos or wrong casing in generated URLs; using an op added in a newer Obsidian CLI version that this handler does not yet whitelist.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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