Skip to content

fix(tools): accept integer OR string for browser_task max_steps - #136

Merged
escapeboy merged 1 commit into
developfrom
fix/browser-task-max-steps-accepts-string
Aug 4, 2026
Merged

fix(tools): accept integer OR string for browser_task max_steps#136
escapeboy merged 1 commit into
developfrom
fix/browser-task-max-steps-accepts-string

Conversation

@escapeboy

Copy link
Copy Markdown
Owner

Fixes Sentry #1084; #937 was the downstream failure of the same run.

Problem

Groq Error [400]: invalid_request_error - tool call validation failed:
parameters for tool browser_task did not match schema:
errors: [`/max_steps`: expected number, but got string]

The model emitted "10" instead of 10. Providers validate the model's tool call against our advertised schema, server-side — the call is rejected before it ever reaches the app, so there is nothing for us to coerce at runtime. Our schema was not wrong; it was simply stricter than what the model reliably produces.

Change

Widen the advertised type to ["integer","string"] on all three browser_task declarations (the inert/disabled one, the sidecar one, and the browser-use Cloud one — the inert one still advertises its schema to the LLM, so it needs it too), and normalise to int at the seam via normaliseMaxSteps().

RawSchema is used rather than AnyOfSchema so this stays a plain JSON Schema type union instead of anyOf, which strict function-calling modes tend to reject.

Tests

  • schema assertion across both transport kinds (browser + browser_use_cloud)
  • behavioural: max_steps: '7' reaches the sidecar as integer 7
  • 231 tests pass across Unit/Domain/Tool + Feature/Domain/Tool; pint + phpstan clean on the touched files

Note on scope

This is a tolerance change, not a claim that the model bug is ours. It stops one malformed generation from failing an entire agent run.

Sentry #1084: Groq rejected the tool call with
`invalid_request_error … parameters for tool browser_task did not match
schema: /max_steps: expected number, but got string` — the model emitted "10"
instead of 10. Providers validate the model's call against our ADVERTISED
schema server-side, so the call never reaches us and we cannot coerce it.

Widen the advertised type to ["integer","string"] on all three browser_task
declarations (disabled/inert, sidecar, browser-use Cloud) and normalise to int
at the seam. RawSchema keeps it a plain JSON Schema type union rather than
anyOf, which strict function-calling modes tend to reject.

#937 (BuildArtifactJob: Failed to build artifact) was the downstream failure of
the same run.
@escapeboy
escapeboy merged commit 09981ba into develop Aug 4, 2026
3 checks passed
@escapeboy
escapeboy deleted the fix/browser-task-max-steps-accepts-string branch August 4, 2026 06:21
escapeboy added a commit that referenced this pull request Aug 4, 2026
failed_jobs had never been pruned and had grown to 1916 rows on production,
the oldest from 2026-04. Every row is a resolved incident, and the volume
drowns the handful that still matter — `queue:failed` shows only the tail, so
the table reads as "3 old entries" when it is nearly two thousand.

`queue:prune-failed --hours=720` keeps 30 days, which is long enough to
investigate a failure after the fact. Verified the schedule entry registers
(`15 4 * * *`, next due 19h).

Found while validating the current failures rather than assuming they were
stale: of the 17 since 2026-07-24, all but one are DistillTeamEventsJob at
01:31 nightly, which stopped after 2026-07-29 (fix #131, 2026-08-01 — six
clean nights since, with `memory:distill-events` confirmed still scheduled and
due, so the silence is a fix and not a job that quietly stopped running). The
remaining one is the browser_task max_steps 400, fixed in #136.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant