JuliusBrussee/caveman · warning
filter monitor has unknown key(s): ${monitorUnknown.sort().j
Error message
filter monitor has unknown key(s): ${monitorUnknown.sort().join(", ")} What it means
Inside the monitor filter object, only keys `id` and `verdict` are accepted. Any extra key (e.g. name, status, version) is collected, sorted, and reported in the error so the caller knows exactly what to remove.
Source
Thrown at packages/cli/src/agent-mcp.ts:492
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");
if (typeof monitor.verdict !== "string" || !["pass", "fail", "error"].includes(monitor.verdict)) {
throw new Error("filter monitor.verdict must be pass, fail, or error");
}
}
}
function optionalEnum(args: JSONObject, key: string, values: string[]): void {
const value = args[key];
if (value !== undefined && (typeof value !== "string" || !values.includes(value))) {
throw new Error(`${key} must be one of ${values.join(", ")}`);
}
}
function validateTraceSearch(args: JSONObject): void {
validateTraceFilters(args);
for (const key of ["from", "to"]) {
const value = args[key];View on GitHub (pinned to 27d5a3981a)
Solutions
- Reduce the monitor filter to exactly { id } or { id, verdict }.
- Pick the keys named in the error message and delete them from the args.
- Filter on other monitor attributes client-side after retrieving results.
Example fix
// before
{ filters: { monitor: { id: "mon_1", verdict: "pass", name: "latency" } } }
// after
{ filters: { monitor: { id: "mon_1", verdict: "pass" } } } Defensive patterns
Strategy: validation
Validate before calling
const monitorKeys = new Set(["id", "verdict"]);
const extra = Object.keys(filters.monitor).filter((k) => !monitorKeys.has(k));
if (extra.length) throw new Error(`monitor has unknown keys: ${extra.join(", ")}`); Type guard
function isCleanMonitor(m: Record<string, unknown>): boolean {
return Object.keys(m).every((k) => k === "id" || k === "verdict");
} Prevention
- Project API monitor entities down to { id, verdict? } before using them as filters.
- Let the sorted key list in the message drive automated cleanup.
When it happens
Trigger: filters.monitor = { id: "mon_1", verdict: "pass", name: "latency" }; copying a fuller monitor object from an API response into the filter.
Common situations: Pasting whole monitor entities from caveman_report/experiment output as filters; guessing unsupported sub-filters.
Related errors
- filter monitor must be an object
- filter monitor.verdict must be pass, fail, or error
- filters must be an object
- unknown trace filter(s): ${unknown.sort().join(", ")}
- filter ${key} must be a non-empty array of non-empty strings
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/6bb1121922d4b4ad.
Report an issue: GitHub.