Skip to content

fix(proxy): actionable errors for bad list_requests/list_sitemap args#566

Open
mikeumus wants to merge 1 commit into
usestrix:mainfrom
mikeumus:fix/proxy-tools-actionable-errors
Open

fix(proxy): actionable errors for bad list_requests/list_sitemap args#566
mikeumus wants to merge 1 commit into
usestrix:mainfrom
mikeumus:fix/proxy-tools-actionable-errors

Conversation

@mikeumus

Copy link
Copy Markdown

Problem

When the agent passes a malformed argument to the Caido proxy tools, it gets back an opaque GraphQL error that references the query document, not its own input — so it can't self-correct and repeats the same failing call. This is especially common with reasoning models served over an OpenAI-compatible endpoint (observed with Kimi-K2.7-Code on Cloudflare Workers AI driving Strix 1.0.4): the proxy tools were the only repeated failures across a 72-turn run.

Two cases:

  • list_requests with an invalid httpql_filter → the agent sees only "Invalid HTTPQL query (line 34, column 3)" (the GraphQL doc line), with no hint about its filter.
  • list_sitemap with a non-i32 parent_id/scope_id (the model passes a URL/host/UUID) → "Invalid ID format, should be an i32" with no guidance.

Fix

Return actionable, self-correcting errors from strix/tools/proxy/tools.py:

  • list_requests: on an HTTPQL parse error, name the offending filter and explain the fix (omit it to list all, or valid HTTPQL examples; note there's no NOT operator).
  • list_sitemap: validate parent_id/scope_id are numeric i32 ids up front, and tell the agent to use a numeric id from a prior list_sitemap response.

Both stay non-fatal so the agent recovers on the next turn. No behavior change for well-formed args.

Testing

Re-ran a full Strix 1.0.4 scan with the patch: the previously-recurring list_requests/list_sitemap errors dropped to zero across 72 turns, and the agent completed recon + spawned specialist agents cleanly.

🤖 Generated with Claude Code

…ap args

When the model passes a malformed argument to the Caido proxy tools, the
agent currently gets back an opaque GraphQL error that references the query
document rather than its own input, so it can't self-correct and repeats
the same bad call. Two cases seen frequently with reasoning models (e.g.
Kimi-K2.7-Code via an OpenAI-compatible endpoint):

- list_requests with an invalid httpql_filter surfaces only
  "Invalid HTTPQL query (line 34, column 3)" — the GraphQL line, not the
  filter. Now it returns a message naming the offending filter and how to
  fix it (omit to list all, or valid HTTPQL examples; note no NOT operator).

- list_sitemap with a non-i32 parent_id/scope_id (a URL/host/UUID) surfaces
  "Invalid ID format, should be an i32". Now it validates up front and tells
  the agent to use a numeric `id` from a prior list_sitemap response.

Both keep the tool call non-fatal and let the agent recover on the next turn.
@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR improves error messages returned by list_requests and list_sitemap when an agent passes malformed arguments, giving reasoning models enough context to self-correct without repeating the same failing call.

  • list_requests: catches exceptions containing "HTTPQL" and replaces the opaque GraphQL error with an actionable message that names the offending filter and provides valid syntax examples.
  • list_sitemap: validates parent_id and scope_id before the API call and returns a structured error with corrective guidance when a non-numeric value (URL, host, UUID) is supplied.

Confidence Score: 3/5

Safe for well-formed inputs, but the scope_id error branch actively misdirects agents to the wrong tool, which could perpetuate the correction loop the PR is trying to eliminate.

The scope_id error message tells the agent to call list_sitemap to obtain a valid scope ID, but scope IDs come from scope_rules. An agent that passes an invalid scope_id will follow this guidance, fetch sitemap entry IDs, and continue passing wrong values — the exact failure the PR aims to fix. The numeric validation also silently admits multi-hyphen strings like '--5', leaving a small gap where the improved error still won't fire.

strix/tools/proxy/tools.py — specifically the scope_id error message branch in the new pre-validation loop.

Important Files Changed

Filename Overview
strix/tools/proxy/tools.py Adds actionable HTTPQL and ID validation errors; the scope_id error message incorrectly directs agents to list_sitemap rather than scope_rules, and the numeric check allows multi-hyphen strings to slip through.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
strix/tools/proxy/tools.py:462-476
**`scope_id` error message points agent to wrong tool**

When `_arg_name == "scope_id"`, the error message tells the agent to "Call `list_sitemap` with no `parent_id` first to get root entries, then pass an entry's numeric `id`." But `scope_id` is a *scope* ID managed via `scope_rules`, not a sitemap entry ID from `list_sitemap`. This sends the agent on a wild-goose chase: it will correctly call `list_sitemap` without `parent_id`, see root domain entries, pick a numeric entry `id`, pass it as `scope_id`, and likely get back wrong results or another error — the exact self-correction failure this PR aims to fix. The guidance in the `scope_id` error branch should reference `scope_rules` instead.

### Issue 2 of 2
strix/tools/proxy/tools.py:463
**`lstrip("-")` allows multiple leading hyphens to bypass validation**

`"--5".lstrip("-")` returns `"5"`, so strings like `"--5"` or `"---42"` pass the digit check and are forwarded to the API, which will still return the opaque `"Invalid ID format"` error this PR aims to avoid. A standard `int()` conversion is the simplest reliable check for a valid i32 string.

```suggestion
        try:
            int(str(_arg_val))
            _valid = True
        except ValueError:
            _valid = False
        if _arg_val is not None and not _valid:
```

Reviews (1): Last reviewed commit: "fix(proxy): return actionable errors for..." | Re-trigger Greptile

Comment on lines +462 to +476
for _arg_name, _arg_val in (("parent_id", parent_id), ("scope_id", scope_id)):
if _arg_val is not None and not str(_arg_val).strip().lstrip("-").isdigit():
return json.dumps(
{
"success": False,
"error": (
f"Invalid {_arg_name}: {_arg_val!r}. {_arg_name} must be a "
"numeric Caido entry id (i32) taken from a prior list_sitemap "
"response's `id` field — not a URL, host, or UUID. Call "
"list_sitemap with no parent_id first to get root entries, then "
"pass an entry's numeric `id`."
),
},
ensure_ascii=False,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 scope_id error message points agent to wrong tool

When _arg_name == "scope_id", the error message tells the agent to "Call list_sitemap with no parent_id first to get root entries, then pass an entry's numeric id." But scope_id is a scope ID managed via scope_rules, not a sitemap entry ID from list_sitemap. This sends the agent on a wild-goose chase: it will correctly call list_sitemap without parent_id, see root domain entries, pick a numeric entry id, pass it as scope_id, and likely get back wrong results or another error — the exact self-correction failure this PR aims to fix. The guidance in the scope_id error branch should reference scope_rules instead.

Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/tools/proxy/tools.py
Line: 462-476

Comment:
**`scope_id` error message points agent to wrong tool**

When `_arg_name == "scope_id"`, the error message tells the agent to "Call `list_sitemap` with no `parent_id` first to get root entries, then pass an entry's numeric `id`." But `scope_id` is a *scope* ID managed via `scope_rules`, not a sitemap entry ID from `list_sitemap`. This sends the agent on a wild-goose chase: it will correctly call `list_sitemap` without `parent_id`, see root domain entries, pick a numeric entry `id`, pass it as `scope_id`, and likely get back wrong results or another error — the exact self-correction failure this PR aims to fix. The guidance in the `scope_id` error branch should reference `scope_rules` instead.

How can I resolve this? If you propose a fix, please make it concise.

# non-numeric ids up front with actionable guidance so the model corrects
# itself instead of repeating an opaque "Invalid ID format" GraphQL error.
for _arg_name, _arg_val in (("parent_id", parent_id), ("scope_id", scope_id)):
if _arg_val is not None and not str(_arg_val).strip().lstrip("-").isdigit():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 lstrip("-") allows multiple leading hyphens to bypass validation

"--5".lstrip("-") returns "5", so strings like "--5" or "---42" pass the digit check and are forwarded to the API, which will still return the opaque "Invalid ID format" error this PR aims to avoid. A standard int() conversion is the simplest reliable check for a valid i32 string.

Suggested change
if _arg_val is not None and not str(_arg_val).strip().lstrip("-").isdigit():
try:
int(str(_arg_val))
_valid = True
except ValueError:
_valid = False
if _arg_val is not None and not _valid:
Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/tools/proxy/tools.py
Line: 463

Comment:
**`lstrip("-")` allows multiple leading hyphens to bypass validation**

`"--5".lstrip("-")` returns `"5"`, so strings like `"--5"` or `"---42"` pass the digit check and are forwarded to the API, which will still return the opaque `"Invalid ID format"` error this PR aims to avoid. A standard `int()` conversion is the simplest reliable check for a valid i32 string.

```suggestion
        try:
            int(str(_arg_val))
            _valid = True
        except ValueError:
            _valid = False
        if _arg_val is not None and not _valid:
```

How can I resolve this? If you propose a fix, please make it concise.

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