JuliusBrussee/caveman · warning
filter status_class values must be 2xx, 4xx, or 5xx
Error message
filter status_class values must be 2xx, 4xx, or 5xx
What it means
The status_class filter accepts only the coarse HTTP classes "2xx", "4xx", "5xx" as array entries. Any other string ("200", "3xx", "success", "error") in the status_class array is rejected.
Source
Thrown at packages/cli/src/agent-mcp.ts:475
"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");
const monitorUnknown = Object.keys(monitor).filter((key) => key !== "id" && key !== "verdict");
if (monitorUnknown.length > 0) throw new Error(`filter monitor has unknown key(s): ${monitorUnknown.sort().join(", ")}`);
if (typeof monitor.id !== "string" || monitor.id.trim() === "") throw new Error("filter monitor.id is required");View on GitHub (pinned to 27d5a3981a)
Solutions
- Convert exact codes to their class: 2xx for 2NN, 4xx for 4NN, 5xx for 5NN.
- Use only the literals "2xx", "4xx", "5xx".
- For semantic filtering, combine status_class with has_error instead of inventing labels.
Example fix
// before
{ filters: { status_class: ["200", "500"] } }
// after
{ filters: { status_class: ["2xx", "5xx"] } } Defensive patterns
Strategy: validation
Validate before calling
function toStatusClass(code: number | string): "2xx" | "4xx" | "5xx" {
const c = typeof code === "number" ? code : parseInt(code, 10);
if (c >= 200 && c < 300) return "2xx";
if (c >= 400 && c < 500) return "4xx";
if (c >= 500 && c < 600) return "5xx";
throw new Error(`no status_class for ${code}`);
} Type guard
function isStatusClass(v: string): v is "2xx" | "4xx" | "5xx" {
return ["2xx", "4xx", "5xx"].includes(v);
} Prevention
- Normalize exact HTTP codes to class form before filtering.
- Pin the vocabulary to the three literals in client code.
When it happens
Trigger: filters.status_class = ["200", "404"]; using "3xx" for redirects; using semantic labels like "success"/"server_error" instead of the class form.
Common situations: Mapping from an internal taxonomy that tracks exact codes or words; a model guessing the format from context.
Related errors
- filters must be an object
- unknown trace filter(s): ${unknown.sort().join(", ")}
- filter ${key} must be a non-empty array of non-empty strings
- 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/baeddedb7622d3f2.
Report an issue: GitHub.