JuliusBrussee/caveman · warning
filter ${key} must be a non-empty array of non-empty strings
Error message
filter ${key} must be a non-empty array of non-empty strings What it means
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.
Source
Thrown at packages/cli/src/agent-mcp.ts:472
"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",
];
for (const key of stringListKeys) {
const value = filters[key];
if (value === undefined) continue;
if (!Array.isArray(value) || value.length === 0 || value.some((entry) => typeof entry !== "string" || entry.trim() === "")) {
throw new Error(`filter ${key} must be a non-empty array of non-empty strings`);
}
if (key === "status_class" && value.some((entry) => !["2xx", "4xx", "5xx"].includes(entry as string))) {
throw new Error("filter status_class values must be 2xx, 4xx, or 5xx");
}
}
for (const key of ["min_cost_usd", "max_cost_usd", "min_total_tokens", "max_total_tokens", "min_latency_ms", "max_latency_ms"]) {
const value = filters[key];
if (value !== undefined && (typeof value !== "number" || !Number.isFinite(value))) {
throw new Error(`filter ${key} must be a finite number`);
}
}
for (const key of ["has_error", "compressed"]) {
const value = filters[key];
if (value !== undefined && typeof value !== "boolean") throw new Error(`filter ${key} must be a boolean`);
}
const monitor = filters.monitor;
if (monitor !== undefined) {
if (!monitor || typeof monitor !== "object" || Array.isArray(monitor)) throw new Error("filter monitor must be an object");View on GitHub (pinned to 27d5a3981a)
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).
Example fix
// before
{ filters: { model: "gpt-4", session_id: [] } }
// after
{ filters: { model: ["gpt-4"] } } Defensive patterns
Strategy: validation
Validate before calling
function toStringList(v: unknown): string[] {
if (v === undefined) return [];
if (!Array.isArray(v) || v.length === 0) throw new Error("must be non-empty array");
return v.map((e) => {
if (typeof e !== "string" || e.trim() === "") throw new Error("entries must be non-empty strings");
return e.trim();
});
} Type guard
function isNonEmptyStringArray(v: unknown): v is string[] {
return Array.isArray(v) && v.length > 0 && v.every((e) => typeof e === "string" && e.trim() !== "");
} Prevention
- Always wrap single filter values in arrays.
- Drop empty arrays instead of sending them.
- Trim and stringify entries before sending.
When it happens
Trigger: filters.model = "gpt-4" (string, not array); filters.workflow = [] (empty); filters.agent = ["", "researcher"]; filters.session_id = [12345].
Common situations: Convenience single-value shorthand that the schema does not accept; programmatically generated arrays that end up empty after filtering; numeric ids not stringified.
Related errors
- filters must be an object
- unknown trace filter(s): ${unknown.sort().join(", ")}
- filter status_class values must be 2xx, 4xx, or 5xx
- filter ${key} must be a finite number
- filter ${key} must be a boolean
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/d71421701217353a.
Report an issue: GitHub.