Frequency:Common
Many tool APIs cap the number of elements allowed in a specific array field of a single request — for example a maximum of 500 line items per invoice-creation call, or 1,000 IDs per bulk-lookup request. When an agent assembles this array dynamically (aggregating results from a prior tool call, paginated upstream source, or a loop that accumulates records), it frequently has no visibility into the cap until the call fails or, worse, the API silently truncates the array and returns success. The agent then proceeds as if all elements were processed, producing incomplete work that looks complete.
Frequency:Common
Many APIs specify an expected retry envelope for failed requests — a minimum delay before retrying (to avoid hammering a recovering service) and a maximum delay (beyond which the server considers the client "gone" and drops queued state, such as an idempotency reservation or a rate-limit grace window). An agent's retry logic, especially generic exponential-backoff code reused across many tools, frequently ignores tool-specific envelope hints (a `Retry-After` header, a documented min/max, or a jittered range) and either retries too fast — getting throttled harder or banned — or waits too long — missing a narrow retry window and losing queued work or an idempotency token.
Frequency:Very Common
Bulk-operation tools commonly enforce a maximum number of operations (rows, records, actions) per batch request, distinct from any single-field array cap — for instance a max of 200 records per bulk-import call or 100 messages per batch-send. Agents that build a batch from dynamic upstream data (a database query, a paginated feed, a fan-out from a previous step) often assemble the request first and only discover the limit when the call is rejected outright, because nothing in the agent's planning path checks the batch's total size against the tool's documented ceiling before dispatch.
Frequency:Common
Beyond the size limit on any single batch, many tools also enforce an aggregate cap on total operations across a rolling window — for example, no more than 10,000 record writes per hour regardless of how they're split across individual batch calls. An agent that correctly chunks each batch to stay under the per-call limit can still violate this rolling aggregate cap if it fires many compliant batches in quick succession, because per-call compliance says nothing about cumulative volume over time. The agent's batching strategy solves the wrong constraint and the job fails partway through with no signal that the two limits are independent.
Frequency:Very Common
Text fields in most APIs have a maximum length — a ticket description capped at 4,000 characters, a product title capped at 200, a commit message capped at 72 characters for the summary line. When an agent generates the content for such a field with an LLM (a summary, a composed message, a generated description), the output length is not guaranteed to respect the target field's limit, since the generation step and the submission step are typically decoupled. The tool either rejects the write outright or, more insidiously, silently truncates the string mid-word or mid-sentence, producing corrupted or nonsensical stored content that the agent has no way of detecting from a success response alone.
Frequency:Common
Query tools built on relational or graph data — GraphQL APIs, ORM-backed REST query endpoints, relational-API query builders — commonly cap how many joins or nested relations can be traversed in a single query, for example a maximum of 5 levels of nested relations. An agent that dynamically constructs a query to satisfy a broad information-gathering goal (e.g., "get the order, its customer, their company, the company's account manager, and that manager's team") can easily exceed this depth without realizing it, especially when the query is assembled programmatically by chaining relation names rather than authored by a person who would naturally notice the query getting unwieldy.
Frequency:Occasional
Many tools reject JSON or other structured payloads once object/array nesting exceeds a fixed depth — commonly somewhere between 10 and 32 levels — to protect their parsers from stack-exhaustion and pathological-input attacks. Agents that build payloads through recursive composition (e.g., chaining tool outputs into a nested config object, recursively expanding a tree-shaped data structure, or composing several sub-tool results into a wrapper object) can produce structures that grow deeper than intended without any single step looking unusual, because the depth accumulates across composition steps that the agent reasons about independently rather than as a whole.
Frequency:Occasional
Query tools that support flexible field selection — most notably GraphQL APIs — often score each incoming query for computational cost (a function of field count, list multipliers, and nesting) and reject any query above a threshold, independent of raw depth or byte size. An agent auto-generating a query to fulfill a broad request ("get me everything about this customer") can easily construct a query that is shallow and small in text but scores extremely high in complexity, because a handful of fields that each return large lists multiply together into a cost the agent has no way to estimate from the query text alone.
Frequency:Occasional
Before a complex query ever executes, the tool's query planner (a database optimizer, a GraphQL resolver-planning phase, a distributed-query coordinator) has to determine an execution strategy — and for sufficiently complex queries, this planning phase itself can time out, independent of and prior to any execution timeout. This produces a distinct failure class from an execution timeout: the query never ran at all, no partial work was done, and no rows were touched, yet the error returned to the agent often looks identical to a generic timeout, so the agent's error handling treats it the same as a slow-but-progressing query and applies the wrong recovery strategy.
Frequency:Very Common
Tools commonly cap the total byte size of a single request — a common ceiling is 1MB, 6MB, or 10MB depending on the platform — independent of any per-field or per-item limits. An agent that builds a request body from accumulated context (conversation history, retrieved documents, concatenated tool outputs, embedded file attachments) can exceed this ceiling even when every individual field is reasonable in isolation, because the agent's context-accumulation logic tracks relevance and completeness, not cumulative serialized byte size against the specific tool being called next.
Frequency:Common
Some tools enforce a hard request timeout with no partial-result mechanism: if the operation isn't fully complete when the clock runs out, the connection is simply dropped and any work done up to that point is discarded rather than returned. An agent that issues a single long-running call (a large data export, a bulk transformation, a synchronous report generation) against such a tool loses all progress when the timeout fires, and — because the response is indistinguishable from other connection failures — the agent typically retries the entire operation from scratch rather than recognizing that the work needs to be restructured into smaller, checkpointable steps.
Frequency:Common
Tools that return large result sets — search results, exports, list endpoints without server-driven pagination — often cap or silently truncate the response payload above a certain size, and critically, this truncation frequently happens without a clear error or a truncation flag in the response body. An agent that reads such a response, parses whatever JSON or text made it through, and proceeds treats a partial result as the complete answer, leading to decisions, summaries, or downstream actions based on missing data with no indication anything was cut off.
Frequency:Occasional
Some tools track retry attempts server-side per operation (keyed by an idempotency key, request ID, or resource ID) and permanently block further retries once a maximum attempt count is reached within a window — for example, a payment gateway that hard-fails an idempotency key after 5 attempts, refusing all further retries regardless of the reason for prior failures. An agent's own retry counter, especially one held in process memory or reset on deploy/restart, frequently loses sync with this server-side count, so the agent believes it has budget for more attempts and keeps retrying into a wall that will never open, wasting time and obscuring the real failure behind a misleading "max retries exceeded" or generic error each time.
Frequency:Common
Multi-step tool jobs (a batch pipeline, an orchestrated workflow, a long-running export composed of several sequential API calls) frequently have an overall wall-clock timeout for the entire job, separate from and often much stricter in aggregate than the sum of individual per-step timeouts an agent budgets for. An agent that allocates time per step, confirming each step completes within its own limit, can still have the whole job killed by the orchestrator's total-job timeout if the sum of otherwise-successful steps exceeds it — a failure the agent's step-by-step success tracking gives it no warning of until the job is terminated mid-flight, discarding whatever aggregate work was in progress at that moment.
Tool operational limits fail when tools have undocumented limits on request size, result size, timeout windows, or concurrent requests, when agents exceed these limits without knowing, or when limits are exceeded gracefully by some tools but cause crashes in others. The 14 operational-limit patterns documented here cover runtime constraints on tool behavior — from per-request size limits, through timeout windows and concurrent-request limits, to payload encoding limits and result set sizes. Operational-limit failures are particularly dangerous because limits are often discovered by exceeding them in production, not during testing with small payloads.
Key Takeaways
- 14 patterns span request/result size limits, timeout windows, concurrent limits, encoding constraints, and payload restrictions.
- Undocumented operational limits and Exceeding limits without graceful handling are most severe: agents don’t know limits exist until hitting them.
- Tool-specific limit behavior varies: one tool returns partial results when limit is hit, another crashes, third silently truncates.
- Testing with small payloads masks operational-limit failures: tests pass but production fails when real payload sizes exceed limits.
Scope
- Request and Result Sizes — Tool request/response size limits, payload encoding limits.
- Concurrency and Timing — Concurrent request limits, timeout windows, batch size limits.
- Graceful Degradation — Behavior when limits are exceeded (crash, truncate, partial results).
When Operational Limits Matter
- Agents process variable-size inputs that may exceed tool limits.
- Multiple concurrent agents use shared tool quota or connection pools.
- Production payloads are significantly larger than test payloads.
Cross-Pattern Insight
Operational-limit failures result from testing with small payloads and undocumented limits. The mitigation is explicit limit discovery and testing: query tools for their limits, test with payloads at 10x, 100x expected size, and verify graceful behavior when limits are exceeded.
Frequently Asked Questions
Query tool documentation and API specs for explicit limit statements. If undocumented, infer limits by testing with increasing payload sizes until failures occur. Set agent limits to stay safely below tool limits (e.g., if tool accepts 1MB, agent sends max 500KB).
Check payload size before calling; if it exceeds limit, either truncate/filter data before calling, split the request into multiple smaller requests, or fail with clear messaging rather than attempting to call and failing mid-operation.
Patterns
| Pattern | Mechanism |
|---|
| Concurrent request limit exceeded | Multiple concurrent requests to same tool; limit hit; additional requests fail or queue |
| Timeout window misconfiguration | Tool has timeout limit; long operations exceed timeout and are killed |
| Request payload size limit exceeded | Request payload exceeds tool maximum; tool rejects or truncates request |
| Result set size limit exceeded | Result set exceeds tool maximum; tool returns partial results or crashes |
| Batch size limit exceeded | Batch operation exceeds maximum batch size; tool fails or processes partial batch |
| Encoding limit exceeded | Payload encoding (JSON, XML, Base64) exceeds tool limit; encoding fails or is truncated |
| Connection pool exhaustion | Concurrent connections to tool exceed pool size; new connections queue or fail |
| Pagination limit exceeded | Pagination offset or page size exceeds tool limits; pagination fails |
| Nested depth limit | Nested data structures exceed tool nesting limit; parsing fails |
| Field count limit exceeded | Record with too many fields exceeds tool limit; additional fields are truncated or ignored |
| Array element limit exceeded | Array with too many elements exceeds tool limit; array is truncated |
| String length limit exceeded | Individual string field exceeds tool maximum length; string is truncated or request fails |
| Streaming timeout | Streaming operation exceeds timeout while waiting for data; stream is closed |
| Memory limit exceeded | Tool operation exceeds memory limit; operation killed or fails |
Total: 14 patterns