can1357/oh-my-pi · error

vault://${op} requires '${name}' query parameter

Error message

vault://${op} requires '${name}' query parameter

What it means

Some ops need mandatory query parameters enforced by `requireParam`: `base` requires `view`, `search` requires `q`, `tag` requires `tag` (or `name`), and `property` requires both `name` and `path`. When the parameter is absent or an empty string, this error names the op and the missing parameter. Empty-string params are stored as `true` by paramsFromUrl and are treated as missing by paramString, so `?q=` also triggers it.

Source

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

	return { files, folders };
}

function formatVaultPathForLink(ref: VaultReference, relativePath: string, trailingSlash: boolean): string {
	const encodedVault = ref.active ? "_" : encodePathComponent(ref.display);
	const encodedPath = encodeRelativePath(relativePath);
	const suffix = trailingSlash ? "/" : "";
	return encodedPath ? `vault://${encodedVault}/${encodedPath}${suffix}` : `vault://${encodedVault}/`;
}

function paramString(params: VaultParams, name: string): string | undefined {
	const value = params[name];
	return typeof value === "string" && value.length > 0 ? value : undefined;
}

function requireParam(params: VaultParams, name: string, op: string): string {
	const value = paramString(params, name);
	if (value) return value;
	throw new Error(`vault://${op} requires '${name}' query parameter`);
}

function validateQueryPath(params: VaultParams, name: string): string | undefined {
	const value = paramString(params, name);
	if (!value) return undefined;
	try {
		validateRelativePath(value.replaceAll("\\", "/"));
	} catch (error) {
		throw toVaultValidationError(error);
	}
	return value;
}

export function buildObsidianCliInvocation(
	parsed: Extract<ParsedVaultUrl, { kind: "file-op" | "vault-op" }>,
): CliInvocation {
	if (parsed.kind === "file-op") {
		const pathArg = `path=${parsed.relativePath}`;

View on GitHub (pinned to 9690622007)

Solutions

  1. Add the named parameter: `?q=<query>` for search, `?view=<view>` for base, `?tag=<name>` (or `?name=`) for tag, and `?name=<property>&path=<file>` for property.
  2. Ensure the value is non-empty — `?q=` counts as missing.
  3. Percent-encode parameter values (encodeURIComponent) so `&`, `=`, `#` in the value don't split the query string.
  4. Validate inputs before building the URL so empty search/tag values are rejected upstream.

Example fix

// before
const url = `vault://_/?op=search&q=${query}`; // query may be ""
// after
if (!query) throw new Error("search requires a non-empty query");
const url = `vault://_/?op=search&q=${encodeURIComponent(query)}`;
Defensive patterns

Strategy: validation

Validate before calling

const REQUIRED: Record<string, string[]> = { base: ["view"], search: ["q"], tag: ["tag", "name"], property: ["name", "path"] };
function hasRequiredParams(op: string, params: URLSearchParams): boolean {
  const req = REQUIRED[op];
  if (!req) return true;
  return req.some(name => params.get(name)?.length) // tag/property need all; simplify per-op as needed
    || (op === "tag" || op === "property" ? req.every(n => params.get(n)?.length) : false);
}

Type guard

function hasParam(params: URLSearchParams, name: string): boolean {
  const v = params.get(name);
  return v !== null && v.length > 0;
}

Try / catch

try {
  const res = await handler.resolve(parseInternalUrl(url));
} catch (err) {
  const m = err instanceof Error && err.message.match(/^vault:\/\/(\S+) requires '(\S+)' query parameter$/);
  if (m) {
    url = withParam(url, m[2], promptFor(m[2])); // supply the named param and retry
  } else throw err;
}

Prevention

When it happens

Trigger: `vault://_/?op=search` (no q), `vault://_/b.base?op=base` (no view), `vault://_/?op=tag` (no tag/name), `vault://_/?op=property&name=status` (no path), or `?q=` with an empty value.

Common situations: Programmatically building URLs where the user's query/tag string was empty; stripping query params during URL rewriting; copy-pasting example URLs and omitting the placeholder parameter.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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