Skip to content

fix(coderd/x/chatd): reject double-encoded tool arguments with actionable errors - #28044

Draft
ibetitsmike wants to merge 2 commits into
mainfrom
mike/chatd-stringified-tool-args
Draft

fix(coderd/x/chatd): reject double-encoded tool arguments with actionable errors#28044
ibetitsmike wants to merge 2 commits into
mainfrom
mike/chatd-stringified-tool-args

Conversation

@ibetitsmike

Copy link
Copy Markdown
Collaborator

Some models occasionally double-encode a structured tool argument as a JSON string, for example {"files": "[...]"} instead of {"files": [...]} for edit_files. Today the Go decoder rejects that with cannot unmarshal string into Go struct field EditFilesArgs.files of type []chattool.editFileEdits, an error that names internal Go types and gives the model nothing actionable, so retries often repeat the same mistake.

Changes

  • toolschema (renamed ValidateUnambiguous to Validate): during the existing pre-hook schema walk, report a typed StringifiedError when a property whose advertised schema declares an array or object carries a string value.
  • toolinput: for that error, the synthetic retryable tool result now says the property is a string, but the schema declares an array and tells the model to Retry with the value provided as JSON directly, not wrapped in a string, instead of the ambiguous-key advice.

Non-goals

No input coercion. Silently re-parsing the string would let a pre_tool_use hook consumer authorize different bytes than the tool executes, which the admission layer exists to prevent. Every input rejected here would fail the tool's Go decoder anyway, so nothing that would have executed is now rejected.

Testing

  • Red-green table cases in toolschema_test.go for top-level, nested, and object-property double-encoding, plus a non-string scalar mismatch that stays with the decoder.
  • TestPartitionStringifiedToolCallInput pins the model-facing retry message.

Mux authored this PR on Mike's behalf.

…able errors

Some models occasionally send a structured tool argument as a
JSON-encoded string, for example {"files": "[...]"} instead of
{"files": [...]}. The Go decoder rejects that with an unmarshal error
naming internal Go types, which models struggle to act on.

Reject such input during the existing pre-hook schema walk instead:
when a property whose advertised schema declares an array or object
carries a string, return a retryable tool error telling the model to
send the value as JSON directly. Every builtin tool decodes those
properties into slices, structs, or maps, so nothing that would have
executed is rejected.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: f638c7652f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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