apache / apache/texera

maxSteps of 0 silently disables the agent's step cap

Open
#7,484 1 comment 0 reactions 1 assignee Claimed by @roshiiiz View on GitHub
Dominant language
Scala
Stars
314
Forks
187
Avg merge
1d 21h
Merged PRs (30d)
214

Description

### What happened?

`TexeraAgent` caps its ReAct loop with `stopWhen: stepCountIs(this.settings.maxSteps)` ([texera-agent.ts:529](https://github.com/apache/texera/blob/main/agent-service/src/agent/texera-agent.ts#L529)). In `ai@7.0.48` that predicate is an **equality** test, not a ceiling:

```js
// node_modules/ai/dist/index.js:4655
function isStepCount(stepCount) {
return ({ steps }) => steps.length === stepCount;
}
```

It is evaluated after a step has run, so `steps.length` is always at least 1. With `maxSteps: 0` the predicate is therefore never satisfied and **the cap is silently disabled** — a model that keeps emitting tool calls is never stopped by it. (A model that returns a plain text answer still terminates, because the loop ends on its own when there are no tool calls to service. The failure needs a tool-calling model, which is the normal case here.)

Nothing rejects the value. `updateSettings` assigns it unchecked:

```ts
// texera-agent.ts:379
if (updates.maxSteps !== undefined) {
this.settings.maxSteps = updates.maxSteps;
}
```

and the HTTP settings endpoint declares it as `maxSteps: t.Optional(t.Number())` ([server.ts:244](https://github.com/apache/texera/blob/main/agent-service/src/server.ts#L244)) with no minimum, so any client can turn the cap off. The default is 100, so this only bites when a value is supplied.

Negative values have the same problem for the same reason.

### How to reproduce?

1. Start the agent service and connect a client.
2. Update the agent settings with `maxSteps: 0` (accepted — no validation rejects it).
3. Send a message that leads the model to keep calling tools.
4. The loop is never stopped by the step cap.

Reproducing it in a unit test is possible but **do not add one**: because the run never ends, the test hangs the suite rather than failing it. This surfaced while writing coverage for `sendMessage`, and it is noted in that spec so nobody tries.

### Version/Branch

1.3.0-incubating-SNAPSHOT (main)

### Expected behavior

`maxSteps` should be validated at both boundaries — rejected at the API schema (`t.Number({ minimum: 1 })`) and clamped or rejected in `updateSettings` — so the cap cannot be disabled by configuration. Alternatively `stopWhen` should use a `>=` comparison rather than the SDK's equality predicate, which would also make the cap robust to a step count that overshoots.

### Additional context

Found while raising `texera-agent.ts` coverage from 51% to 99.8%. The reachable-but-untestable nature of this path is the reason no regression test accompanies the report.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.