TL;DR
Form state carries at most twenty-five rows, and the warning is an instruction a builder can delete. The cap is on the form path, not the data path.
Yes — form state carries at most twenty-five rows. The agent does not error when it hits the ceiling. It answers, and the answer is built on whatever arrived.
The part worth knowing is where the cap applies and where it does not, because that distinction is also the fix.
Is there a documented row cap?
There is, and it sits in the agent instruction block Microsoft publishes as a starting point:
"A tool call response can include up to 25 rows of data as form state. Generate a warning if the form state contains 25 rows of data."
Two separate things live in that sentence, and separating them is the whole article:
| The sentence says | What it is |
|---|---|
| A response carries at most twenty-five rows of form state | A property of the platform. Not configurable, not negotiable |
| Generate a warning when it does | An instruction to the model. Text in a prompt |
The cap is real whatever you do. The warning exists only if the instruction survives into your agent.
Does hitting the cap produce an error?
No, and that is the design worth understanding. Microsoft's mitigation is a behavioural one — it asks the model to notice and say so, rather than the platform refusing.
Which means the failure is silent by default, and the boundary condition is exactly the one that reads as success: a full page of results. An agent that receives twenty-five rows has no way to know whether the answer was twenty-five or two hundred. It sees a complete-looking set and reasons over it.
Microsoft's instruction block guards a closely related failure in the same section, and the pairing is telling:
"When instructed to create new data, and the creation fails, DO NOT retrieve existing data instead."
Both rules exist to stop an agent reporting a partial or substituted result as a whole one — which is the false-success problem in its read-side form.
Do not delete either line when you customise the instructions. They read like boilerplate and they are the two sentences doing correctness work.
Why is twenty-five rows easier to hit than it sounds?
Because the filtering that would narrow a grid below the ceiling is itself limited. Limitation eight of ten:
"The MCP server doesn't support advanced filters on grids. For example, it doesn't support the 'before,' 'after,' and 'between' operators for date columns. It supports only the 'matches' operator for filtering."
No date range. For a transactional ERP that is the single most natural way to cut a result set down, and on the form path it is unavailable. Ask about open orders in a period and the grid you are filtering is the whole grid.
There is one published exception worth knowing, because it reads like an escape hatch and is narrower than it looks: (lessThanDate(x:int)) "is a valid value for a grid date column filter" — a relative, one-sided comparison, not a range.
Two other form behaviours compound it. Tabs "are closed by default" and the agent must open them to reach controls, and the form_find_controls tool "accepts only one search term per call." More calls to assemble less context — and outside Copilot Studio every one of those calls is billed.
What does a truncated answer look like from the outside?
Like a good one, which is the entire problem.
A reviewer reading the agent's reply sees a well-formed list of records, correctly retrieved, correctly described. There is no ellipsis, no "showing 25 of 212", no marker of any kind — the response is simply built from a smaller set than the question implied.
Compare that with the failure modes people design for. A timeout is visible. A permission error names itself. A wrong value can be spotted by someone who knows the data. A short answer that is internally consistent survives every one of those checks, because nothing about it is wrong except its completeness.
That is why the mitigation Microsoft chose is a warning rather than a validation: there is nothing for the platform to reject. The response is valid. It is the inference drawn from it that is not.
Does the cap apply to data tools as well?
Read Microsoft's words closely: the limit is on rows "as form state."
Form state is what the form path returns. The data tools are a different family — they read through data entities over OData, and Microsoft describes that path as needing "fewer tool calls" and giving "better performance" for standard operations.
So the honest answer is that the twenty-five-row sentence is scoped to form state and does not, on its face, describe the OData read path. We are not asserting that data tools are uncapped — Microsoft does not say that either, and an unbounded claim about a limit that is not documented would be a guess. What is documented is the scope of this cap, and it is the form path.
That makes tool-family choice a correctness decision and not only a performance one, which is the routing question this cluster's comparison covers.
What should you actually do about it?
Three moves, in order of return. These are ours:
- Keep the warning instruction, verbatim. It costs one line and it is the only thing that surfaces the condition at all. Treat it as load-bearing when you rewrite the prompt.
- Route list-shaped reads to data tools. If the job is "find the records", that is the family Microsoft tells you to prefer anyway, and the documented cap is on the other path.
- Design the question to be narrow. With only a matches operator on the form path, narrowing has to come from the request rather than the filter — one customer, one order, one item, rather than a period.
And treat a twenty-five-row answer as unproven. Not wrong, unproven. That is a cheap habit and it is the one that catches the case where the number mattered.
If an agent is giving you answers that look complete, the row cap is worth ten minutes of someone's attention. Bring a query that returned a full page. https://cognilium.ai
Sources
This article is part of our work on AI in tandem with Dynamics 365.
Share this article
What Microsoft ships, what it does not, and the layer we build where a general assistant runs out.

