Repository navigation
Description
Steps to reproduce
With accessibility (semantics) enabled, Flutter web's semantic <input> is in the DOM and typeable before the framework knows the field is focused. Everything typed in that window is then erased, not merely dropped.
flutter create fieldprobe- Replace
lib/main.dartwith:
import 'package:flutter/material.dart';
void main() => runApp(const ProbeApp());
class ProbeApp extends StatelessWidget {
const ProbeApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
body: Padding(
padding: const EdgeInsets.all(24),
child: TextField(controller: TextEditingController()),
),
),
);
}flutter build weband servebuild/webover HTTP.- Open the page, then enable semantics by activating the "Enable accessibility" placeholder:
document.querySelector('flt-semantics-placeholder').click();- Focus the field and deliver input in the same task — this is the focus-to-input handoff, and it is what any fast input source (automation,
locator.fill(), a password manager, an injected paste) does:
const i = document.querySelector('input');
i.focus();
for (const ch of 'ABCDEFGHIJ') {
i.value += ch;
i.dispatchEvent(new InputEvent('input', {bubbles: true, data: ch, inputType: 'insertText'}));
}
setTimeout(() => console.log(JSON.stringify(i.value)), 1200);Expected results
The field holds "ABCDEFGHIJ".
Actual results
The field holds "". Every character typed before the framework activated the field is erased.
With input paced more slowly, the leading characters alone are lost — one character at 60ms/char, more the faster input arrives — because the erase happens once, at a fixed moment after focus, and destroys whatever arrived before it. Typing 9123456783 into a freshly focused field yields 123456783.
Without semantics enabled, nothing is lost at any speed: the engine creates and focuses its own hidden input within a microtask of the pointer event, so there is no window.
Cause
In lib/web_ui/lib/src/engine/semantics/text_field.dart:
SemanticsTextEditingStrategy.enable()only stores the config; it installs no DOM listeners.- The DOM element is hooked up later, from
SemanticTextField.update(), which callsSemanticsTextEditingStrategy.activate()on the next semantics update afterhasFocusbecomes true. activate()callsDefaultTextEditingStrategy.enable(), which runs
if (lastEditingState != null) { setEditingState(lastEditingState); }
and writes the framework'sTextEditingValue(empty, for an untouched field) onto the DOM input.
So the browser accepts input into the element from the moment it is focused, the framework never sees that input because no input listener is attached yet, and the framework's stale value is then applied over it.
Re-entering the same field loses nothing, because activate() early-returns when activeTextField == textField.
Impact
Any input delivered faster than the activation frame loses its leading characters silently, and the user sees a plausible-looking but wrong value. In our case three address fields were each stored missing their leading characters — a home address a nurse is dispatched to.
Flutter Doctor output
Reproduced on Flutter 3.41.9 (stable), Dart 3.11.5, Chromium, macOS. lib/web_ui/lib/src/engine/semantics/text_field.dart has no related change between 3.41.9 and 3.47.7, so current stable behaves the same.
Related
Possibly adjacent, both closed: #129324 (unable to type with ensureSemantics enabled) and #192792 (focused field loses DOM focus on an ancestor rebuild). This report is specifically about input accepted by the DOM element between browser focus and activate() being overwritten by the framework's stale editing state.
Activity
suryaKommana2662 commentedon Oct 12, 2026
@Vamsi-Annabathula Thanks for the report. I tested the provided reproduction steps on Flutter 3.47.7 stable using Chrome on macOS. After enabling semantics and running the JavaScript input script, the field retained the full value (ABCDEFGHIJ). I could not reproduce the reported input loss in this test. Could you please confirm whether the issue still occurs on the latest stable version?
Flutter Doctor Output
Street-PuNk commentedon Oct 26, 2026
I can reproduce this on 3.47.7 stable (engine
deb287481e, Dart 3.13.5), Chromium 152 on Windows 11,flutter build web --release.I think the original snippet can look like it passes for two reasons, because
input.valueis not what the framework sees:document.hasFocus() === false, e.g. the snippet is run from the DevTools console while DevTools has focus). The browser then does not dispatchfocusto the input, the framework is never told about the focus,activate()never runs and nothing overwrites the DOM.input.valuereads"ABCDEFGHIJ"whilecontroller.textis"". The input is still lost, just invisibly.document.activeElementwas already the input right after semantics was enabled), soi.focus()is a no-op andactivate()returns early.A variant that avoids both: the same app with one extra line that shows the framework value:
Click once anywhere on the page (so the document has focus), enable semantics, then run:
Result (every round I tried): right after, the DOM holds the typed text. 1.2 s later it is reverted to the previous framework value, and the
framework valueline never shows the typed characters.We hit the same thing with real, trusted input from CDP:
Input.dispatchMouseEventclick on the field followed immediately byInput.insertText. The text is visible in the field, but the framework value is empty and the form is submitted empty. With a ~2 s pause after the click it works. As a workaround in our test tooling we wait until the semantics strategy is active (a probemousedownon the input getsdefaultPreventedbypreventDefaultForMouseEvents()) before inserting text.github-actions commentedon Nov 2, 2026
Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now.
If you find this problem please file a new issue with the same description, what happens, logs and the output of 'flutter doctor -v'. All system setups can be slightly different so it's always better to open new issues and reference the related ones.
Thanks for your contribution.