{"record":{"id":"9dc9d92d3cf7e227","repo":"JuliusBrussee/caveman","slug":"filter-monitor-verdict-must-be-pass-fail-or-erro","errorCode":null,"errorMessage":"filter monitor.verdict must be pass, fail, or error","messagePattern":"filter monitor\\.verdict must be pass, fail, or error","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/cli/src/agent-mcp.ts","lineNumber":495,"sourceCode":"  }\n  for (const key of [\"min_cost_usd\", \"max_cost_usd\", \"min_total_tokens\", \"max_total_tokens\", \"min_latency_ms\", \"max_latency_ms\"]) {\n    const value = filters[key];\n    if (value !== undefined && (typeof value !== \"number\" || !Number.isFinite(value))) {\n      throw new Error(`filter ${key} must be a finite number`);\n    }\n  }\n  for (const key of [\"has_error\", \"compressed\"]) {\n    const value = filters[key];\n    if (value !== undefined && typeof value !== \"boolean\") throw new Error(`filter ${key} must be a boolean`);\n  }\n  const monitor = filters.monitor;\n  if (monitor !== undefined) {\n    if (!monitor || typeof monitor !== \"object\" || Array.isArray(monitor)) throw new Error(\"filter monitor must be an object\");\n    const monitorUnknown = Object.keys(monitor).filter((key) => key !== \"id\" && key !== \"verdict\");\n    if (monitorUnknown.length > 0) throw new Error(`filter monitor has unknown key(s): ${monitorUnknown.sort().join(\", \")}`);\n    if (typeof monitor.id !== \"string\" || monitor.id.trim() === \"\") throw new Error(\"filter monitor.id is required\");\n    if (typeof monitor.verdict !== \"string\" || ![\"pass\", \"fail\", \"error\"].includes(monitor.verdict)) {\n      throw new Error(\"filter monitor.verdict must be pass, fail, or error\");\n    }\n  }\n}\n\nfunction optionalEnum(args: JSONObject, key: string, values: string[]): void {\n  const value = args[key];\n  if (value !== undefined && (typeof value !== \"string\" || !values.includes(value))) {\n    throw new Error(`${key} must be one of ${values.join(\", \")}`);\n  }\n}\n\nfunction validateTraceSearch(args: JSONObject): void {\n  validateTraceFilters(args);\n  for (const key of [\"from\", \"to\"]) {\n    const value = args[key];\n    if (value !== undefined && typeof value !== \"string\") throw new Error(`${key} must be a string`);\n  }\n  optionalEnum(args, \"date_field\", [\"occurred\", \"updated\"]);","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/agent-mcp.ts#L477-L513","documentation":"monitor.verdict, when provided as a string, must be exactly one of \"pass\", \"fail\", or \"error\". Any other value (\"passed\", \"ok\", \"failed\", \"success\") is rejected — note the past-tense forms are not accepted.","triggerScenarios":"monitor: { id: \"mon_1\", verdict: \"passed\" }; using UI labels like \"Success\"/\"OK\" instead of the wire tokens.","commonSituations":"Translating display labels into filters; a model inflecting the token (\"failed\" instead of \"fail\").","solutions":["Use the exact tokens: \"pass\", \"fail\", \"error\".","Omit verdict to match all verdicts for a monitor id.","Normalize your app's verdict vocabulary to these three values at the boundary."],"exampleFix":"// before\n{ filters: { monitor: { id: \"mon_1\", verdict: \"passed\" } } }\n\n// after\n{ filters: { monitor: { id: \"mon_1\", verdict: \"pass\" } } }","handlingStrategy":"validation","validationCode":"if (monitor.verdict !== undefined && ![\"pass\", \"fail\", \"error\"].includes(monitor.verdict)) {\n  throw new Error(\"verdict must be pass|fail|error\");\n}","typeGuard":"function isMonitorVerdict(v: unknown): v is \"pass\" | \"fail\" | \"error\" {\n  return v === \"pass\" || v === \"fail\" || v === \"error\";\n}","tryCatchPattern":null,"preventionTips":["Use the exact imperative tokens, never past tense.","Omit verdict to match all outcomes for a monitor id."],"tags":["mcp","validation","filters","enum","monitor"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}