Hmbown/CodeWhale · warning · Error
The practice text field changed. Run the check again.
Error message
The practice text field changed. Run the check again.
What it means
The check resolves the located 'Practice text' AX element to a concrete backend target via resolve_element. If the reply says found: false, the element record captured moments earlier no longer matches the live UI — the field's AX path or window changed between snapshot and resolution. The error asks you to rerun so a fresh snapshot is taken.
Solutions
- Re-run the background check — a fresh state snapshot usually resolves the element successfully.
- Run the check on a quiet desktop (no other apps opening/closing) so AX indices stay stable.
- If it reproduces every time, capture app logs and report an AX indexing bug against the practice app.
Defensive patterns
Strategy: retry
Try / catch
try {
await runBackgroundCheck({ bundle });
} catch (e) {
if (String(e.message).includes("practice text field changed")) {
return runBackgroundCheck({ bundle }); // stale AX snapshot — one retry
}
throw e;
} Prevention
- Keep the desktop static (no window open/close/focus churn) while the check runs.
- Retry on stale-element messages before treating the check as failed.
- Report recurring cases with app logs — they usually indicate AX indexing bugs, not user error.
When it happens
Trigger: In runBackgroundCheck, call('resolve_element', { app_ref: { pid: child.pid }, windowIndex: entry.windowIndex, path: entry.path }) returns { found: false } after the text field was found in the state snapshot.
Common situations: The practice window moved, reopened, or re-indexed between get_app_state and resolve_element; UI animations delaying layout; another window stealing focus and changing window order.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- The practice Apply button changed. Run the check again.
- element press was not acknowledged
- The practice controls could not be read. Check…
- Agent continuation target is no longer retained
- Agent not found
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/5687f85bceadd436.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/app/background-check.mjs:65
const state = await call("get_app_state");
if (demoDirectory) {
fs.mkdirSync(demoDirectory, { recursive: true });
// AX can register before WindowServer makes a new window capturable.
// Retry only this read, before sending any input, within the check limit.
while (true) {
try { await call("screenshot", { app_ref: { pid: child.pid }, path: path.join(demoDirectory, "01-ready.png") }); break; }
catch (error) {
if (controller.signal.aborted || !error.message.includes("not capturable")) throw error;
await delay(100, undefined, { signal: controller.signal });
}
}
}
const entry = state.elements.find(element => element.role === "AXTextField" && element.label === "Practice text");
const apply = state.elements.find(element => element.role === "AXButton" && element.label === "Apply");
if (!entry || !apply) throw new Error("The practice controls could not be read. Check Accessibility permission and retry.");
// Backend targets are resolved AX records, using the exact state index.
const focus = await call("resolve_element", { app_ref: { pid: child.pid }, windowIndex: entry.windowIndex, path: entry.path });
if (!focus.found) throw new Error("The practice text field changed. Run the check again.");
await call("left_click", { target: { ...focus.element, type: "element", app_ref: { pid: child.pid } } });
const phrase = "Background check complete 🐋";
await call("type", { text: phrase });
if (demoDirectory) await call("screenshot", { app_ref: { pid: child.pid }, path: path.join(demoDirectory, "02-entered.png") });
const button = await call("resolve_element", { app_ref: { pid: child.pid }, windowIndex: apply.windowIndex, path: apply.path });
if (!button.found) throw new Error("The practice Apply button changed. Run the check again.");
await call("left_click", { target: { ...button.element, type: "element", app_ref: { pid: child.pid } } });
await until(() => applied);
if (applied.value !== phrase) throw new Error("The text received by the practice window did not match. Check the app log and retry.");
const capture = await call("screenshot", { app_ref: { pid: child.pid }, path: path.join(scratch, "practice.png") });
if (demoDirectory) fs.copyFileSync(capture.file, path.join(demoDirectory, "03-verified.png"));
if (capture.app_ref?.pid !== child.pid || !capture.pixels?.w || !capture.pixels?.h) throw new Error("The practice window screenshot could not be verified. Check Screen Recording permission.");
const count = latest.samples;
await until(() => latest.samples > count);
const isolated = latest.samples > 0 && latest.pointerChanges === 0 && latest.foregroundChanges === 0;
return { ok: isolated, edited: true, screenshot: true, samples: latest.samples, pointerChanges: latest.pointerChanges, foregroundChanges: latest.foregroundChanges,
message: isolated ? "Text entered, Apply verified and the practice window captured. Your foreground app and pointer stayed unchanged."
: "Edit and screenshot verified. Your app or pointer moved during the check, so background isolation is inconclusive." };View on GitHub (pinned to 73e0f67d83)