Nithya
02/05/2026, 4:41 AM[Promptfoo] Konstantine
02/05/2026, 10:20 PMNithya
02/07/2026, 6:37 PMNithya
02/07/2026, 6:38 PM[Promptfoo] Konstantine
02/09/2026, 5:07 PMproviders:
- id: https://your-api.com/endpoint
config:
# ... your existing config ...
transformResponse: |
(json, text, context) => {
const status = context?.response?.status;
if (status >= 400) {
return { output: `PROVIDER_ERROR (HTTP ${status}): ${json?.error || text}` };
}
return { output: json?.output || text };
}
The HTTP provider accepts all status codes by default, so transformResponse will run on 400s, 500s, etc. Then you can write assertions against the error output like normal.
One exception: HTTP 429 (rate limit) responses are intercepted by the retry layer before reaching transformResponse, so this won't catch those, but rate limits are auto-retried anyway so I'm guessing they aren't your main concern.
Here are some docs links if you want to dive deeper:
- https://www.promptfoo.dev/docs/providers/http/#response-transform
- https://www.promptfoo.dev/docs/red-team/troubleshooting/multiple-response-types/Nithya
02/10/2026, 5:11 AM[Promptfoo] Konstantine
02/10/2026, 5:44 AMResults: 10 passed, 3 failed, ✗ 2 errors (78%)
Errors (like rate limits) are counted distinctly from assertion failures.
A few more things that might help:
- Re-run only errored tests:` promptfoo eval --retry-errors` will automatically re-run just the test cases that hit provider errors
- Filter in the web UI: promptfoo view has a display mode dropdown where you can filter to "Errors" only
- Export and count: promptfoo eval -o results.json, then filter by failureReason === 2 (that's the error code, distinct from 1 which is assertion failure)Nithya
02/10/2026, 5:45 AM[Promptfoo] Konstantine
02/10/2026, 5:56 AMNithya
02/10/2026, 6:00 AM[Promptfoo] Konstantine
02/10/2026, 4:29 PM