Skip to content

[compass] Fix: seat_element set_value reports "performed" on a Chrome drop-down list that ignores it - #28

Merged
skulitom merged 3 commits into
mainfrom
compass/anode-fix-2026-10-08-set-value-ignored
Oct 9, 2026
Merged

skulitom merged 3 commits into
mainfrom
compass/anode-fix-2026-10-08-set-value-ignored

Conversation

@skulitom

@skulitom skulitom commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Report

C:\DEV\Compass\ANODE-BUGS.md, B-026 (compass-followup, 2026-10-08, while recording the C-042 web-form guide in the seat): on installed Anode 0.11.0, seat_element set_value with "Team" on a Chrome <select> (role ComboBox, options Free/Team/Enterprise) returned {"performed":"set_value"}, but a fresh seat_observe still read "Free" and the page showed Free. The same call worked on the page's text fields. An agent that trusts "performed" submits the form with the wrong choice.

Root cause

AccessibilityReader.Act called ValuePattern.SetValue and answered performed as soon as the call returned. UI Automation only reports whether the provider accepted the call. Chrome accepts SetValue on a <select> and doesn't change the choice. Nothing checked the effect.

Fix

set_value now reads the control back (AccessibilityReader.SetValue):

  • The value took: performed, as before. Anode waits up to 1.5 s, reading every 50 ms, because Chrome shows a change a moment after the call. The wait ends as soon as the value changes, so a working field answers as quickly as before.
  • The control reformatted it (for example a number field adding separators): performed, plus value with what the control reads now (clipped to 500 characters). The text summary shows it too.
  • The control still shows its old value after 1.5 s: the action fails with: "The control accepted set_value but still showed its old value 1500 ms later. It ignored the change, or took it and kept its old text (a tag field that adds a tag, a value it rewrites, a change still pending). Drop-down lists such as Chrome's ignore set_value: expand the list and select the option, or click it. Inspect again before you retry." The drop-down sentence appears only for a ComboBox. The message never quotes the control's text, because the pipe server writes handler errors to anode.log.
  • The control can't be read back after the call (gone, or a provider error): performed, with a note that the value was sent but not read back. The call did go out, so a failure here would have told the agent nothing happened.

The observation is consumed either way, as before. The seat_element tool description, docs/DESKTOP-TOOLS.md, docs/PROTOCOL.md (the optional value) and the CHANGELOG say this.

How it was tested

  • New quick check desktop ignored set_value: a hidden in-process window (never shown) whose UIA provider is a ComboBox with a ValuePattern. It applies, ignores (like Chrome's <select>), applies 300 ms later, or uppercases the value. The check goes through the real Observe and Act. It also checks that the failure doesn't quote the control and gives the drop-down advice, and that the summary shows a reformatted value. The hidden-window plumbing of desktop unknown control types moved into a shared Hosted helper, which this check uses too. That check still passes.

  • Mutation runs (file restored byte for byte after each, then rebuilt):

    • With the old one-line set_value put back, the check fails: a late-applied value was reported as performed before the control had it.
    • With the "still the old value" branch turned into success, the check fails: an ignored value was reported as performed.
  • FOCUS test command (scripts\build.ps1 -QuickTest -OutputDirectory artifacts\pkg-build): 96/96 pass at each commit. Debug selftest --quick: pass.

  • No seat, lease, input, browser or Android command was run, and the installed Anode's anode-control pipe wasn't touched.

  • Second review: a fresh read-only Claude subagent (Codex is at its usage limit until Fri 9 Oct 22:15). First pass, on f08518f: no P1. Two P2s:

    • The failure quoted the control's old value into anode.log. Fixed in b884144.
    • The live path is untested. It needs a seat; see below.

    Its P3s are fixed in b884144: a wider read-back catch, an honest message with the drop-down advice only for a ComboBox, the reformatted value in the text summary, and PROTOCOL.md. A re-check of b884144 found no new P1/P2. Its two P3s are fixed in 1f7d5a1: the summary quotes the value, and the check now also covers the read-back catch and a text field. A mutation with that catch disabled fails the check.

Still to check in a real seat

  • On Chrome, set_value on a <select> should now fail with the message above instead of reporting performed.
  • On Chrome and Notepad text fields, set_value should still succeed. This is the main risk: it holds only if Chrome's accessibility update arrives within the 1.5 s wait in a hidden seat. If it doesn't, every Chrome <input> set_value would now fail where it used to work.
  • scripts/test-desktop.ps1 runs WinForms TextBox set_value through the new read-back.

The followup's fixture page is C:\DEV\Compass\scratch\compass-followup\c042-media\form\index.html.

🤖 Generated with Claude Code

skulitom and others added 2 commits October 8, 2026 23:24
seat_element set_value on a Chrome <select> returned {"performed":"set_value"}
while the list kept its old choice, so an agent could submit a form with the
wrong option. AccessibilityReader.Act now reads the control back after
SetValue: it waits up to 1.5 s for the value to change (Chrome shows a change
a moment later), fails with a message that says to expand the list and select
the option when the control still reads its old value, and returns what the
control reads when it reformatted the value.

The new quick check "desktop ignored set_value" drives a hidden in-process
ComboBox that applies, ignores, applies late or reformats the value. The
hidden-window plumbing of "desktop unknown control types" moves into a shared
Hosted helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e may have taken (review)

From the second review of B-026's fix:
- The failure quoted up to 200 characters of the control's old value, and the
  pipe server logs every handler error to anode.log, so a field's contents
  could reach the log. The message no longer quotes the control.
- It now says the control may have taken the change and kept its old text (a
  tag field, a value it rewrites, a change still pending), and gives the
  "expand the list" advice only for a ComboBox.
- A COMException, timeout or InvalidOperationException while reading back,
  after the value was sent, now answers "performed" with a note instead of a
  failure that reads as "nothing happened".
- The text summary shows what a reformatting control now reads (sanitised),
  and PROTOCOL.md lists the optional `value`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

…ck catch and a text field (review)

From the re-check of b884144: the text summary quotes what a reformatting
control reads, or says "(empty)", so app text isn't read as part of Anode's
note. The quick check now also covers a control that goes away after the
value is sent (performed, "could not be read back") and a text field that
ignores the value (no drop-down advice).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@skulitom

skulitom commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

Compass merge: ready to merge, merging now

Tested by compass-merge on 2026-10-09 on head 1f7d5a1, which already sits on the current main 63a80f8, so this is the code that lands:

Review (whole diff):

  • The read-back waits at most 1.5 s, well inside the desktop worker's 10 s deadline, and stops as soon as the value changes.
  • A value the control already holds returns at once. Password controls are still refused before this point, and a SetValue that throws still fails as before.
  • The failure never quotes the control's text (the pipe server logs errors), and only a ComboBox gets the drop-down advice.
  • The check refactor keeps every AppBar assertion. Each check now has one 20 s limit instead of 10 s per call.
  • Still untested (as the PR says): a real Chrome text field in a hidden seat. If Chrome's accessibility update ever takes longer than 1.5 s there, set_value on an <input> would now fail. Please check this in a seat before the next release.

Second opinion: the fixer's fresh Claude subagent reviews (two passes, no open P1 or P2). The Codex CLI is at its usage limit until 22:15 today, and Codex's GitHub review hit the same limit on this PR.

Undo: git revert of the squash commit.

@skulitom
skulitom merged commit 72ac2a8 into main Oct 9, 2026
1 check passed
@skulitom
skulitom deleted the compass/anode-fix-2026-10-08-set-value-ignored branch October 9, 2026 00:30
skulitom added a commit that referenced this pull request Oct 9, 2026
…landed as a squash

Resolved with #28's head (1f7d5a1) as the merge base, so the diff against main is still
exactly 1f7d5a1..0acceef. The tree is unchanged from 0acceef.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
skulitom added a commit that referenced this pull request Oct 9, 2026
…down notes

compass-merge's review of #27 (2026-10-09):
- GUIDE-DESKTOP-APP: build before `lease acquire`, so a long build can't
  expire the 120 s lease; mention `--ttl 600`; scale screenshot points back
  to seat pixels before `seat_click`.
- GUIDE-ANDROID, ANDROID, TROUBLESHOOTING: `anode android` needs Anode
  running; only `--json` shows `booted`.
- GUIDE-WEB-FORM: sign in before the agent takes the lease; take the next
  element ID from `seat_wait`'s own reply; scale screenshot points back;
  #28 and #29 fix the `<select>` behaviour in the next release; one
  `seat_type` call types at most about 3,000 characters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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