By Lucas Yoris · Performate
Hallucinations and APIs: Why AI-Drafted Load Scripts Still Need Validation
API hallucinations in AI-drafted k6 scripts: common failure modes, how to review paths and checks, and why smoke tests beat prompt tweaks.
The AI-generated k6 script looks perfect—clean imports, plausible URLs, checks with confident names. You scale to fifty virtual users and discover 40% of requests hit /v1/checkout while production moved to /v2 three sprints ago. AI hallucinations in load testing are rarely dramatic; they are mundane route drift, silent checks, and JSONPath guesses that never fail because the assertion was wrong.
Models optimize for coherence, not your router table. In this guide you will learn the top hallucination classes in k6 drafts, a strict validation workflow before scale, and how smoke choreography catches bogus endpoints faster than prompt engineering alone.
Why AI drafts fail even when they "look right"
If the model never saw your private spec, it invents. If it saw an outdated OpenAPI export, it ships outdated confidently.
- Route drift:
/v1vs/v2, dropped microservice prefixes, trailing slash mismatches. - Auth fantasy: refresh flows that omit cookies or headers your gateway requires.
- Correlation guesses: extracting IDs from field names that do not exist in live JSON.
- Silent checks: assertions that cannot fail—
check(true)equivalents dressed as validation.
Pair structure with k6 scenario types explained; wrong arrival rates hurt as much as wrong URLs once you scale. Optional model features do not verify your API—they restate what you showed them.
When bigger prompts do not fix bad inputs
Refresh OpenAPI excerpts, collection exports, or prior k6 per release. Diff AI output against the approved spec line by line for critical paths—contract vs performance tests thinking keeps hallucinations from sneaking through as "probably fine."
If hallucinated routes hit internal admin hosts or unexpected regions, treat review as a potential SSRF lesson—URL allowlists belong in human review, not only in prompts.
Practical k6 implementation: adversarial smoke before scale
Treat every AI-generated http call as guilty until a 1 VU smoke against a known environment proves innocence.
Example script (illustrative—not a production-ready test). Shows validation helpers and negative checks AI drafts often omit.
What this example demonstrates:
- Spec-aligned paths: constants sourced from env vars you verify against OpenAPI before merge.
- Adversarial checks: body fields required by product—not just status 2xx.
- Negative probe in setup: intentional bad auth once to prove checks fail when they should.
- Ordered smoke choreography: auth → read → write before any ramp scenario runs.
import http from 'k6/http';
import { check, fail } from 'k6';
const BASE = __ENV.API_BASE || 'https://staging.example.com';
const CHECKOUT_PATH = __ENV.CHECKOUT_PATH || '/v2/checkout';
export const options = {
scenarios: {
smoke_validation: {
executor: 'shared-iterations',
vus: 1,
iterations: 3,
maxDuration: '2m',
tags: { phase: 'smoke' },
},
},
thresholds: {
http_req_failed: ['rate==0'],
checks: ['rate>0.99'],
},
};
export function setup() {
// Prove checks are not silent: bad token must fail once
const bad = http.post(
`${BASE}${CHECKOUT_PATH}`,
JSON.stringify({ sku: 'SKU-100', qty: 1 }),
{
headers: { 'Content-Type': 'application/json', Authorization: 'Bearer invalid' },
tags: { phase: 'negative_probe' },
},
);
const negativeOk = check(bad, { 'bad auth not 2xx': (r) => r.status === 401 || r.status === 403 });
if (!negativeOk) {
fail('Checks may be silent—fix before scaling load');
}
return { token: __ENV.TOKEN };
}
export default function (data) {
const catalog = http.get(`${BASE}/catalog?page=1`, {
headers: { Authorization: `Bearer ${data.token}` },
tags: { route: 'catalog' },
});
check(catalog, {
'catalog 2xx': (r) => r.status >= 200 && r.status < 300,
'catalog has items array': (r) => Array.isArray(r.json('items')),
});
const checkout = http.post(
`${BASE}${CHECKOUT_PATH}`,
JSON.stringify({ sku: 'SKU-100', qty: 1 }),
{
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${data.token}` },
tags: { route: 'checkout' },
},
);
check(checkout, {
'checkout 2xx': (r) => r.status >= 200 && r.status < 300,
'checkout orderId present': (r) => typeof r.json('orderId') === 'string',
});
}
Patterns that work
- Line-by-line diff against OpenAPI or Postman export for every
httpURL in the draft. - Smoke order: auth-only → read-heavy → writes last—stop early if steps fail (debug failing load test runbook).
- Break mock data once: delete a required field; checks must fail.
- Human baseline: compare AI output to minimal k6 script template for APIs.
Anti-patterns to avoid
- Skipping smoke because "the script looked fine."
- Scaling before negative probes prove checks fire.
- Letting models infer pagination, idempotency keys, or internal hostnames.
Pro tip (example command): verbose logging on 1 VU smoke.
k6 run smoke-validate.js -e CHECKOUT_PATH=/v2/checkout --http-debug=full -e TOKEN=$STAGING_TOKEN
What this command demonstrates: full request/response traces expose wrong paths and headers before concurrency hides them in aggregates.
Decision framework: when to reject vs fix AI drafts
| Situation | Recommended action |
|---|---|
| URL not in approved spec/collection | Reject draft; fix source doc or re-prompt with attached export |
| Check passes on intentional bad data | Block merge; adversarial smoke failed |
| Auth flow missing gateway cookie/header | Human patch; do not scale until cookie jar matches staging |
| Dynamic ID from wrong JSON field | Fix extraction; rerun 1 VU with logged bodies |
| AI invented admin or internal URL | Security review; add allowlist before any run |
| Paths valid, thresholds unknown | Proceed to smoke; calibrate thresholds separately (k6 thresholds examples) |
Reject the draft if any critical journey URL cannot be traced to the current release artifact.
Fix and re-smoke if paths align but checks or auth helpers are incomplete.
Escalate to security if unexpected hosts, regions, or SSRF patterns appear—regardless of prompt quality.
Observability, documentation, and next steps
Validation only sticks when it is repeatable across releases.
- Attach OpenAPI/collection SHA to every AI draft PR—same identifier used in smoke CI.
- Log
CHECKOUT_PATHand base URL env vars in run metadata for audit trails. - Store 1 VU smoke logs for failed reviews so the next draft diff is explicit.
- Add a "validation passed" checklist item before scale scenarios run in Performate or CI.
- Pair script review with AI-assisted k6 script generation safety upstream policies.
How Performate simplifies AI script validation
Below is a concrete workflow example for the checkout smoke path this article discusses.
Example: catch hallucinations before scale
- Import the current Postman collection or OpenAPI as the source of truth—not pasted chat snippets. Problem solved: AI drafts start from routes your team already approved.
- Generate or paste an AI draft into the editor only after the import syncs. Problem solved: fewer invented paths because folder names match real requests.
- Run 1 VU smoke with verbose logging from the desktop runner. Problem solved: wrong URLs surface in the integrated report before you touch arrival rate.
- Add adversarial checks on orderId and catalog arrays—mirror the k6 example above. Problem solved: silent checks fail in setup, not at 50 VUs.
- Diff exported k6 against the collection before promoting to scale scenarios. Problem solved: drift is visible in version control, not tribal knowledge.
- Promote to load scenario only after smoke passes—same requests, higher executors (Postman to k6 step-by-step if that is your import path).
That workflow maps to this post's cta: Postman-style imports, k6 runs, and AI assistance stay practical when validation is mandatory—not optional.
Closing takeaway
AI hallucinations in load testing drop when specs are attached, smokes are mandatory, and checks are adversarial—prompt engineering cannot substitute. Diff every URL against the release artifact, prove checks fail on bad data, then scale.
Run your next AI draft through 1 VU smoke with a negative auth probe before raising VUs—and reject any path that is not in this week's approved export.
Ready to optimize your API performance?
Discover how Performate connects Postman-style workflows, k6, and AI-assisted insights so performance testing stays practical for real teams.