{"record":{"id":"64f2606a124462a4","repo":"can1357/oh-my-pi","slug":"unsupported-vault-vault-op-rawop","errorCode":null,"errorMessage":"Unsupported vault:// vault op: ${rawOp}","messagePattern":"Unsupported vault:// vault op: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/vault-protocol.ts","lineNumber":202,"sourceCode":"}\n\nfunction isFileOp(rawOp: string): rawOp is FileOp {\n\treturn FILE_OPS[rawOp as FileOp] === true;\n}\n\nfunction isVaultOp(rawOp: string): rawOp is VaultOp {\n\treturn VAULT_OPS[rawOp as VaultOp] === true;\n}\n\nfunction parseVaultOp(rawOp: string, hasFilePath: boolean): FileOp | VaultOp {\n\tif (hasFilePath) {\n\t\tif (!isFileOp(rawOp)) {\n\t\t\tthrow new Error(`Unsupported vault:// file op: ${rawOp}`);\n\t\t}\n\t\treturn rawOp;\n\t}\n\tif (!isVaultOp(rawOp)) {\n\t\tthrow new Error(`Unsupported vault:// vault op: ${rawOp}`);\n\t}\n\treturn rawOp;\n}\n\nexport function parseVaultUrl(input: string | InternalUrl): ParsedVaultUrl {\n\tconst url = typeof input === \"string\" ? parseInternalUrl(input) : input;\n\tconst host = url.rawHost || url.hostname;\n\tconst params = paramsFromUrl(url);\n\tconst rawOp = typeof params.op === \"string\" ? params.op : undefined;\n\tconst { rawPathname, relativePath, hasPath, isDirectory } = decodeVaultPath(url);\n\n\tif (!host && !hasPath && !rawOp) {\n\t\treturn { kind: \"list-vaults\", url: url.href, params };\n\t}\n\n\tconst ref = makeVaultReference(host);\n\tif (rawOp) {\n\t\tconst op = parseVaultOp(rawOp, relativePath.length > 0);","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/vault-protocol.ts#L184-L220","documentation":"When a vault:// URL has an `op` query parameter but no file path, `parseVaultOp` validates the op against the vault-op whitelist (search, daily, daily-path, tags, tag, tasks, orphans, unresolved, deadends, bases, bookmarks, recents, templates, aliases, properties, property). Unknown values throw this error. Matching is exact and case-sensitive.","triggerScenarios":"`vault://_/?op=Search&q=x`, `vault://_/?op=graph`, `vault://myvault?op=list` — any op value not in VAULT_OPS on a path-less URL.","commonSituations":"Guessing op names instead of using the documented set; casing mistakes; referencing ops from other tools or newer CLI versions not yet whitelisted.","solutions":["Use a supported vault op: search, daily, daily-path, tags, tag, tasks, orphans, unresolved, deadends, bases, bookmarks, recents, templates, aliases, properties, property.","Fix casing and hyphenation exactly as listed (e.g. `daily-path`, not `dailyPath`).","If you meant a per-file operation, include the file path in the URL so it is validated against FILE_OPS instead.","Add genuinely new CLI ops to VAULT_OPS in vault-protocol.ts."],"exampleFix":"// before\nconst url = \"vault://_/?op=Search&q=meeting\"; // wrong casing\n// after\nconst url = \"vault://_/?op=search&q=meeting\";","handlingStrategy":"validation","validationCode":"const VAULT_OPS = [\"search\",\"daily\",\"daily-path\",\"tags\",\"tag\",\"tasks\",\"orphans\",\"unresolved\",\"deadends\",\"bases\",\"bookmarks\",\"recents\",\"templates\",\"aliases\",\"properties\",\"property\"];\nfunction isValidVaultOp(op: string): boolean { return VAULT_OPS.includes(op); }\n// check isValidVaultOp(op) before building a path-less vault://?op= URL","typeGuard":"function isVaultOpValue(op: string): op is \"search\"|\"daily\"|\"daily-path\"|\"tags\"|\"tag\"|\"tasks\"|\"orphans\"|\"unresolved\"|\"deadends\"|\"bases\"|\"bookmarks\"|\"recents\"|\"templates\"|\"aliases\"|\"properties\"|\"property\" {\n  return [\"search\",\"daily\",\"daily-path\",\"tags\",\"tag\",\"tasks\",\"orphans\",\"unresolved\",\"deadends\",\"bases\",\"bookmarks\",\"recents\",\"templates\",\"aliases\",\"properties\",\"property\"].includes(op);\n}","tryCatchPattern":"try {\n  const res = await handler.resolve(parseInternalUrl(url));\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Unsupported vault:// vault op:\")) {\n    // fall back to vault://_/ (vault listing) or a supported op\n  } else throw err;\n}","preventionTips":["Copy op names from the documented whitelist rather than guessing","Use exact casing/hyphenation (`daily-path`, not `dailyPath`)","If an op needs a file, it belongs in FILE_OPS with a path-bearing URL","Validate op strings at the boundary where user input enters your URL builder"],"tags":["url","validation","whitelist","api-misuse"],"backgroundTag":"unsupported-operation","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}