Repository navigation
Description
Describe the bug
Two input-handling gaps make write calls report success while changing nothing:
-
Empty strings are treated as "not provided". In
issue_writemethod: update,title: ""andbody: ""are skipped, and the call returns success with no change. A body can't be cleared, and an empty title is not refused.update_pull_requestwithtitle: ""sends the edit and gets a REST 422 (PullRequest.title (missing_field)), so the two tools behave differently. -
Unknown or misspelled parameters are silently dropped. No write tool's input schema sets
additionalProperties: false(all 19 write tools in the default toolsets, checked viatools/list), and the typed decode ignores extra keys. Examples:issue_writeupdate with onlylabelzreturns success and changes nothing.delete_filewithshadeletes without any check (see the separate delete_file issue).actions_listwithper_page(the schema saysperPage) uses the default page size.
update_pull_requestwith only a misspelled field (titel) does fail, but only because its "No update parameters provided." guard (pullrequests.go:1080) catches the empty update.
Related: #3605 / PR #3630 handle misspelled required names (pull_number vs pullNumber) by adding aliases. This issue is about optional fields, where nothing fails.
Same class on the read side: #3316 (open; pull_request_read silently ignores inapplicable pagination params; PRs #3317 and #3336). The *Provided flags for labels/assignees came from #2596 / PR #2600.
Code (main 99d6d65, unchanged since v2.1.0): pkg/github/issues.go:3415-3421 (if title != "" / if body != ""); labels and assignees already use explicit "provided" flags (:3423). Write-tool input schemas have no AdditionalProperties set.
Affected version
v2.1.0 (image sha256:f6056fc1…0f8a, commit 4bcdcdf) and main nightly (image sha256:48bc16d0…338f, revision 99d6d65).
Steps to reproduce the behavior
- Issue N has title
T, bodyB, labels[c, d].
(123 stands for the issue/PR number.) - Call:
Result:
{"name":"issue_write","arguments":{"method":"update","owner":"OWNER","repo":"REPO","issue_number":123,"body":""}}OK {"id":"…","url":".../issues/N"}. The body is stillB. - Same with
"title":"". Result: OK, and the title is stillT. - Call:
Result: OK, and the labels are still
{"name":"issue_write","arguments":{"method":"update","owner":"OWNER","repo":"REPO","issue_number":123,"labelz":["a"]}}[c, d]. - For comparison,
update_pull_request{"pullNumber":P,"title":""}returnsfailed to update pull request: Validation Failed PullRequest.title (missing_field).
Expected vs actual behavior
Expected:
- An empty
bodyclears the body. An emptytitleis rejected with a clear message. - An unknown parameter is rejected and named (
unknown parameter "labelz"), so the caller can correct it.
Actual: success with no change in each case, so an agent believes the update happened.
Suggested fix: decide presence by key, not by value, for title/body (as LabelsProvided already does). Set additionalProperties: false on write-tool input schemas, or reject unknown keys during the typed decode, at least for write tools.
Logs
issue_write update body="" -> OK {"id":"6277311572","url":".../issues/N"} body unchanged
issue_write update title="" -> OK … title unchanged
issue_write update labelz=["a"] -> OK … labels unchanged
update_pull_request title="" -> ISERROR failed to update pull request: Validation Failed / PullRequest.title (missing_field)
update_pull_request titel="x" -> ISERROR No update parameters provided.
tools/list: additionalProperties unset on all 19 write tools (default toolsets)
Same results on v2.1.0 and main. In an earlier run, issue_write method: create with lables also created the issue without labels. That case was not re-run here, to avoid creating issues.
Found during an independent audit of v2.1.0 on a throwaway org and private test repo. Prepared with AI assistance (Claude Code); reproduced by two independent test runs before filing.
Activity