JuliusBrussee/caveman · error
filter 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
For list-typed filter keys (workflow, agent, model, provider, error_code, status_class, ...), validateTraceFilters requires the value to be a non-empty array whose every element is a non-empty string. A missing key is fine (undefined is skipped), but a wrong shape, an empty array, or an empty/whitespace/non-string element throws this error.
Solutions
- Wrap single values in an array: workflow: ['deploy']
- Ensure the array is non-empty — drop the key entirely if there are no values
- Filter/trim entries and remove empties before sending
- Convert non-string entries to strings or drop them
Example fix
// before
searchTraces({ filters: { workflow: 'deploy' } });
searchTraces({ filters: { agent: [] } });
// after
searchTraces({ filters: { workflow: ['deploy'] } });
// omit agent entirely when empty Defensive patterns
Strategy: validation
Validate before calling
function assertStringList(filters, key) {
const v = filters?.[key];
if (v === undefined) return;
if (!Array.isArray(v) || v.length === 0 || v.some((e) => typeof e !== 'string' || e.trim() === '')) {
throw new Error(`filter ${key} must be a non-empty array of non-empty strings`);
}
} Type guard
function isNonEmptyStringArray(v) {
return Array.isArray(v) && v.length > 0 && v.every((e) => typeof e === 'string' && e.trim() !== '');
} Try / catch
try {
await searchTraces({ filters });
} catch (error) {
const m = error.message.match(/^filter (\w+) must be a non-empty array/);
if (m) {
const v = filters[m[1]];
filters[m[1]] = typeof v === 'string' ? [v] : (v ?? []).map(String).filter((s) => s.trim());
}
} Prevention
- Always wrap single values in an array before sending list filters
- Omit the key entirely instead of passing []
- Trim and drop empty entries before sending
- Coerce non-string entries with String() or drop them
When it happens
Trigger: Passing filters like { workflow: 'deploy' } (string instead of array), { agent: [] } (empty array), { model: ['gpt-4', ''] } (empty string element), or { provider: [123] } (non-string element).
Common situations: Clients passing a single value instead of an array; trimming leading to empty strings; serializers turning empty filters into []; numeric ids passed without string conversion.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- filter must be a boolean
- filter must be a finite number
- filter monitor must be an object
- filter status_class values must be 2xx, 4xx, or 5xx
- filters must be an object
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/d71421701217353a.
Report an issue: GitHub.
Appendix: 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 3ee70a1026)