{"record":{"id":"d71421701217353a","repo":"JuliusBrussee/caveman","slug":"filter-key-must-be-a-non-empty-array-of-non-emp","errorCode":null,"errorMessage":"filter ${key} must be a non-empty array of non-empty strings","messagePattern":"filter (.+?) must be a non-empty array of non-empty strings","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/cli/src/agent-mcp.ts","lineNumber":472,"sourceCode":"    \"model\",\n    \"provider\",\n    \"error_code\",\n    \"auth_mode\",\n    \"runtime_mode\",\n    \"cache_status\",\n    \"session_id\",\n    \"client_user_hash\",\n    \"trace_id\",\n    \"member_user_id\",\n    \"api_key_id\",\n    \"optimization_id\",\n    \"status_class\",\n  ];\n  for (const key of stringListKeys) {\n    const value = filters[key];\n    if (value === undefined) continue;\n    if (!Array.isArray(value) || value.length === 0 || value.some((entry) => typeof entry !== \"string\" || entry.trim() === \"\")) {\n      throw new Error(`filter ${key} must be a non-empty array of non-empty strings`);\n    }\n    if (key === \"status_class\" && value.some((entry) => ![\"2xx\", \"4xx\", \"5xx\"].includes(entry as string))) {\n      throw new Error(\"filter status_class values must be 2xx, 4xx, or 5xx\");\n    }\n  }\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\");","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/agent-mcp.ts#L454-L490","documentation":"Each list-valued trace filter (workflow, agent, model, provider, error_code, auth_mode, runtime_mode, cache_status, session_id, client_user_hash, trace_id, member_user_id, api_key_id, optimization_id, status_class) must be a non-empty array containing only non-empty, non-whitespace strings. An empty array, a bare string, or an array with \"\" / \" \" / numbers throws with the offending key named.","triggerScenarios":"filters.model = \"gpt-4\" (string, not array); filters.workflow = [] (empty); filters.agent = [\"\", \"researcher\"]; filters.session_id = [12345].","commonSituations":"Convenience single-value shorthand that the schema does not accept; programmatically generated arrays that end up empty after filtering; numeric ids not stringified.","solutions":["Wrap single values in an array: model: [\"gpt-4\"].","Drop empty arrays entirely (omit the key) instead of sending [].","Map values to trimmed strings and filter out empties before calling: values.map(String).map(s=>s.trim()).filter(Boolean)."],"exampleFix":"// before\n{ filters: { model: \"gpt-4\", session_id: [] } }\n\n// after\n{ filters: { model: [\"gpt-4\"] } }","handlingStrategy":"validation","validationCode":"function toStringList(v: unknown): string[] {\n  if (v === undefined) return [];\n  if (!Array.isArray(v) || v.length === 0) throw new Error(\"must be non-empty array\");\n  return v.map((e) => {\n    if (typeof e !== \"string\" || e.trim() === \"\") throw new Error(\"entries must be non-empty strings\");\n    return e.trim();\n  });\n}","typeGuard":"function isNonEmptyStringArray(v: unknown): v is string[] {\n  return Array.isArray(v) && v.length > 0 && v.every((e) => typeof e === \"string\" && e.trim() !== \"\");\n}","tryCatchPattern":null,"preventionTips":["Always wrap single filter values in arrays.","Drop empty arrays instead of sending them.","Trim and stringify entries before sending."],"tags":["mcp","validation","filters","arrays"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}