🚨 Risks & Common Mistakes

Risks & Common Mistakes: Building an agent without hardening it against the risks below is like shipping a Selenium suite that has never been run against a slow network, a missin

Building an agent without hardening it against the risks below is like shipping a Selenium suite that has never been run against a slow network, a missing element, or a locale change — the mechanism is exact: each risk below is a specific, previously-invisible assumption (the model will always call a tool, temperature=0 means identical output, a log file is always small enough) that holds true in a demo and breaks under real production conditions, exactly like a test suite that only ever ran on a fast local network and never learned to handle a timeout. Here is the question worth sitting with: if each of these risks sounds obvious once named, why do so many real agent deployments hit them anyway? Because none of them are visible in a quick demo — a demo run is short, uses a small trusted log, never hits a rate limit, and never gets tricked by injected text; every one of these failure modes only appears at the scale and adversarial conditions of real production traffic, exactly the way a flaky test only reveals itself after enough real-world runs, never in a single clean demo. Java comparison: this is the same gap between "the happy path compiles and runs once" and "the code survives a production load test" — a working demo and a hardened system are different bars, and the difference is precisely the edge cases enumerated below. The QA stake: this list is not meant to scare you off building agents — it is the reference checklist a senior holds themselves to before calling an agent "production ready," the same role the Claude AI page's Risks tab plays for using Claude day to day.

Eight Failure Modes, One Discipline: Harden Before Shipping

Each entry below names a real failure shape, its mechanical cause, and the fix — not to frighten you away from building agents, but as the concrete checklist a senior tester runs through before calling an agent-based feature ready to ship.

The key was committed directly in source instead of being read from an environment variable — the same mistake covered on the Claude AI page's Access & Setup tab, shown here as a real incident.

The code had no backoff/retry handling around the API call — the same resilience gap as not handling a flaky network call in an integration test.

The code assumed the model always returns a tool call, but the model can legitimately return plain text instead — for example, deciding the task needs no tool, or asking a clarifying question. This is exactly the "if not message.tool_calls: break" branch from the Build Your Own Test Agent tab's loop, and this entry shows what happens if you skip it.

The while True loop has no hard iteration cap, so if the model gets stuck in an unproductive call pattern — or a tool keeps returning an error the model keeps retrying the same way — the loop never naturally terminates.

A broadly-scoped tool WAS registered and the model was successfully tricked by adversarial text in the data it read — this only causes real damage because the dangerous tool existed and was callable in the first place.

Examples were pulled directly from real support tickets or bug reports without anonymizing them, and a fine-tuned model can sometimes reproduce fragments of its training data in outputs — the same privacy risk class as pasting unsanitized logs, but now baked permanently into a model artifact instead of a single conversation.

Temperature=0 makes the sampling step deterministic in principle — pick the highest-probability token every time — but does not guarantee byte-for-byte identical output across all providers and infrastructure; other backend factors can introduce tiny variation.

A large log file was pasted directly into the prompt without checking its token count first — the context window is a hard limit (from the Context Window tab), not a soft guideline.

Step by Step: Verifying an Agent Before Production

Confirm no API key is hardcoded anywhere in the code.

Confirm a max-step limit exists.