CloakHQ/CloakBrowser · error · ElementNotEditableError
Element ${selector} failed editable check: element is not ed
Error message
Element ${selector} failed editable check: element is not editable What it means
With 'editable' in checks (used by typing/filling actions), the probe found the element but data.editable === false — the field is read-only or not an editable control.
Source
Thrown at js/src/human/actionability.ts:121
// Pre-scroll actionability
// ---------------------------------------------------------------------------
async function stealthActionable(
pageOrFrame: Page | Frame,
selector: string,
checks: ReadonlySet<CheckName>,
): Promise<void> {
const world = getWorld(pageOrFrame);
if (!world) throw new StealthWorldUnavailableError();
const { status, data } = await evalParsed(world, buildActionableJs(selector));
if (status === UNSUPPORTED) throw new UnsupportedHumanizeSelectorError(selector);
if (status === EVALUATION_FAILED) throw new StealthEvaluationError(selector);
if (status === NOT_FOUND) throw new ElementNotAttachedError(selector);
if (status !== OK || !data) throw new StealthEvaluationError(selector);
if (checks.has('visible') && !data.visible) throw new ElementNotVisibleError(selector);
if (checks.has('enabled') && !data.enabled) throw new ElementNotEnabledError(selector);
if (checks.has('editable') && !data.editable) throw new ElementNotEditableError(selector);
}
async function readBox(
pageOrFrame: Page | Frame,
selector: string,
): Promise<{ x: number; y: number; width: number; height: number } | null> {
const world = getWorld(pageOrFrame);
if (!world) throw new StealthWorldUnavailableError();
const { status, data } = await evalParsed(world, buildBoxJs(selector));
if (status === OK && data?.box) return data.box;
if (status === NOT_FOUND) return null;
if (status === UNSUPPORTED) throw new UnsupportedHumanizeSelectorError(selector);
throw new StealthEvaluationError(selector);
}
export async function ensureActionable(
pageOrFrame: Page | Frame,View on GitHub (pinned to d6bad5de26)
Solutions
- Verify the selector resolves to the actual editable input element, not a wrapper
- Wait for readonly to clear if the field unlocks after loading: waitForFunction checking !input.readOnly
- For non-editable controls (selects, date pickers) use fill/select/keyboard APIs instead of typing
- Pass a checks set without 'editable' if the control is legitimately readonly and you use a different interaction
Example fix
// before await humanType(page, '.date-display', '2024-01-01'); // after await humanFill(page, 'input[name="date"]', '2024-01-01');
Defensive patterns
Strategy: validation
Validate before calling
if ((await page.locator(sel).getAttribute('readonly')) !== null) { /* use fill/select instead of typing */ } Type guard
function isElementNotEditableError(e: unknown): e is ElementNotEditableError {
return e instanceof Error && /failed editable check/.test(e.message);
} Try / catch
try { await humanType(page, sel, txt); } catch (e) { if (isElementNotEditableError(e)) await page.locator(sel).fill(txt); else throw e; } Prevention
- Target the real input element, not wrappers
- Wait for readonly masks to unlock before typing
- Use fill/select APIs for non-editable controls
When it happens
Trigger: ensureActionable with 'editable' on readonly inputs (readonly attribute), non-input elements targeted by humanType/humanFill, or inputs made readonly while a request is in flight.
Common situations: Typing into readonly/date inputs, masks that toggle readonly during formatting, fields locked during submission, or a wrong selector landing on a div/span instead of the input.
Related errors
- Element ${selector} failed enabled check: element is disable
- Isolated-world DOM evaluation failed for ${selector}
- Element ${selector} failed attached check: element not found
- Element ${selector} failed visible check: element is not vis
- Element ${selector} failed timeout check: timeout expired be
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/de73e48d75fc91be.
Report an issue: GitHub.