{"record":{"id":"889fc4e059768323","repo":"JuliusBrussee/caveman","slug":"caveman-agent-error-rate-guardrail-max-must-be-in","errorCode":null,"errorMessage":"caveman agent: error-rate guardrail max must be in [0,1]","messagePattern":"caveman agent: error-rate guardrail max must be in \\[0,1\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/primitives.ts","lineNumber":458,"sourceCode":"  quality: QualityGrader[];\n  guardrails?: EvalGuardrail[];\n}): EvalDefinition {\n  if (options.id.trim() === \"\") throw new Error(\"caveman agent: eval id is required\");\n  if (options.quality.length === 0) throw new Error(\"caveman agent: eval needs at least one quality grader\");\n  const known = new Set([\"contains\", \"tool_called\", \"exact_match\", \"json_schema\"]);\n  for (const grader of options.quality) {\n    if (!known.has(grader.type)) {\n      throw new Error(`caveman agent: unknown grader ${(grader as { type: string }).type}`);\n    }\n  }\n  for (const guardrail of options.guardrails ?? []) {\n    if (guardrail.type === \"latency_threshold\" &&\n        (!Number.isSafeInteger(guardrail.p95_ms) || guardrail.p95_ms <= 0)) {\n      throw new Error(\"caveman agent: latency guardrail requires positive integer p95_ms\");\n    }\n    if (guardrail.type === \"error_rate\" &&\n        (!Number.isFinite(guardrail.max) || guardrail.max < 0 || guardrail.max > 1)) {\n      throw new Error(\"caveman agent: error-rate guardrail max must be in [0,1]\");\n    }\n  }\n  const tools = options.tools ?? { mode: \"fixture\" as const };\n  if (tools.mode === \"live\" && !tools.sandbox) {\n    throw new Error(\"caveman agent: live eval tools require an explicit sandbox\");\n  }\n  return Object.freeze({\n    kind: \"eval\",\n    id: options.id,\n    approved: options.approved ?? false,\n    required: options.required ?? true,\n    input: options.input,\n    tools,\n    quality: Object.freeze([...options.quality]),\n    guardrails: Object.freeze([...(options.guardrails ?? [])]),\n  });\n}\n","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/primitives.ts#L440-L476","documentation":"Thrown by evalFixture() when an 'error_rate' guardrail's max is not a finite number in [0, 1]. The guardrail bounds the tolerated failure fraction, so negatives, values above 1, NaN, Infinity, and percent-style values like 5 (meaning 5%) are all invalid at construction.","triggerScenarios":"Passing guardrails: [{ type: 'error_rate', max: 5 }] (percent, not fraction), max: -0.1, max: 1.5, max: NaN, or a string '0.02' from config.","commonSituations":"Config authored in percent ('maxErrorRate: 2' meaning 2%) instead of the fraction 0.02; SLO spreadsheets exporting percentages; forgetting to divide by 100 when converting an external SLO.","solutions":["Express the cap as a fraction: 0.02 for 2%, 0 for zero tolerance, 1 for allowing everything","Convert percentages at the config boundary: max: percent / 100","Validate with Number.isFinite(v) && v >= 0 && v <= 1 in your fixture loader"],"exampleFix":"// before (SLO doc says 'max error rate 2%')\nevalFixture({ id: 'e1', input: q, quality: q1, guardrails: [{ type: 'error_rate', max: 2 }] });\n\n// after\nevalFixture({ id: 'e1', input: q, quality: q1, guardrails: [{ type: 'error_rate', max: 0.02 }] });","handlingStrategy":"validation","validationCode":"function toErrorRateMax(raw: unknown): number {\n  const n = typeof raw === 'number' ? raw : Number(raw);\n  if (!Number.isFinite(n) || n < 0 || n > 1) throw new Error(`error_rate max must be a fraction in [0,1], got ${String(raw)} (use 0.02 for 2%)`);\n  return n;\n}","typeGuard":"function isErrorRateMax(value: unknown): value is number { return typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= 1; }","tryCatchPattern":null,"preventionTips":["Name the config field maxErrorRateFraction to make units obvious","Divide percentages by 100 at the loader boundary","Unit-test the conversion once and reuse it"],"tags":["validation","eval","guardrail","numeric"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}