Hmbown/CodeWhale · error · RuntimeError

value_verification_failed

Error message

value_verification_failed

What it means

set_value verifies its own write: after setTextContents succeeds, it reads the text back via queryText and compares it to the requested value. Any mismatch raises RuntimeError("value_verification_failed"), because an unverifiable write is treated as a failed edit rather than a silently ambiguous one.

Solutions

  1. Set a value that survives the field's normalization exactly (match its formatting)
  2. Read the field's current format first and conform to it
  3. Compare loosely in your own retry wrapper and accept normalized-equivalent results
  4. Use keyboard input plus your own verification if the field auto-transforms text

Example fix

// before
await backend.set_value({ target: "#amount", value: "1234.500" }) // field normalizes to 1234.5
// after
await backend.set_value({ target: "#amount", value: "1234.5" });
Defensive patterns

Strategy: try-catch

Validate before calling

// check the field's current formatting and conform your value to it
const current = await backend.get_value?.(target);
if (current && normalizes(value) !== normalizes(current)) console.warn("field may reformat this value");

Try / catch

try { return await backend.set_value({ target, value }); } catch (e) { if (String(e).includes("value_verification_failed")) { const actual = await backend.get_value?.(target); if (normalizedEquals(actual, value)) return { accepted: true }; } throw e; }

Prevention

When it happens

Trigger: The readback text (text.getText(0, characterCount)) differs from extra — the widget normalized the value (trimmed whitespace, reformatted dates/numbers), truncated it, or an async edit had not settled before readback.

Common situations: Setting values into fields the app reformats (currency, dates, phone numbers); writing to fields with auto-trim or auto-complete that mutates input; very large values that the widget truncates.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/bf7c5ef88e1d1c9a. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/plugins/computer-use/src/backends/linux.mjs:709

    set_value: async ({ target, value }) => {
      // Select a supported interface before sending input. A refused write or
      // failed readback must never trigger a second, ambiguously applied edit.
      const out = await atspiResolve(target, `    state = found.getState()
    if not state.contains(pyatspi.STATE_ENABLED):
        raise RuntimeError("element_disabled")
    try:
        editor = found.queryEditableText()
    except NotImplementedError:
        editor = None
    if editor is not None:
        if not state.contains(pyatspi.STATE_EDITABLE):
            raise RuntimeError("element_read_only")
        if not editor.setTextContents(extra):
            raise RuntimeError("value_rejected")
        text = found.queryText()
        after = text.getText(0, text.characterCount)
        if after != extra:
            raise RuntimeError("value_verification_failed")
    else:
        import math
        desired = float(extra)
        if not math.isfinite(desired):
            raise RuntimeError("invalid_value")
        numeric = found.queryValue()
        numeric.currentValue = desired
        after = numeric.currentValue
        if after != desired:
            raise RuntimeError("value_verification_failed")
    print(json.dumps({"ok": True, "after": after}))`, String(value));
      if (!out.ok) throw new ExecError(`set_value failed: ${out.code}`);
      return { action_sent: true, strategy: "a11y", verified: true, after: out.after };
    },
    select_text: async () => { throw new ExecError("select_text is not implemented on the linux backend — fail-closed"); },
    perform_action: async ({ target, action }) => {
      const body = `    a = found.queryAction()
    names = [a.getName(i) for i in range(a.nActions)]

View on GitHub (pinned to 73e0f67d83)