Hmbown/CodeWhale · critical · AggregateException
Unicode input failed: " + failure.Message + "; key-up…
Error message
Unicode input failed: " + failure.Message + "; key-up recovery failed: " + cleanup.Message
What it means
When injecting a Unicode character (KEYEVENTF_UNICODE down/up pair), the backend catches InputDeliveryException from the SendChecked of the pair. If exactly one event was inserted (only the key-down), it attempts to release that key once with a key-up; if that recovery also fails, it throws an AggregateException combining both messages, then otherwise rethrows the original failure. This prevents leaving a stuck virtual key after partial injection.
Solutions
- Read both inner exceptions: the original injection failure and the key-up cleanup failure, and fix the underlying cause (usually elevation/UIPI per error 284)
- Ensure the session stays unlocked and elevated consistently for the duration of text input
- Wrap text sending in try/catch and, on failure, send a harmless key (e.g. VK_SHIFT up) or reset keyboard state to clear any stuck key
- Retry the whole SendString after the environment stabilizes; never retry only the character that half-landed without clearing state
Example fix
// before
SendString(text);
// after
try { SendString(text); }
catch (AggregateException e) {
// e.InnerExceptions[0] = original SendInput failure, [1] = key-up recovery failure
ClearKeyboardState();
throw;
} Defensive patterns
Strategy: try-catch
Try / catch
try { SendString(text); }
catch (AggregateException e) {
foreach (var ex in e.InnerExceptions) Log(ex.Message);
ClearKeyboardState(); // release any stuck key
throw;
}
catch (InputDeliveryException e) { Log(e.Message); throw; } Prevention
- Never leave a half-injected Unicode pair without a key-up recovery
- Suspend screen-lock/UAC prompts during automated typing
- Reset keyboard state after any failed injection batch
- Send long text in chunks so failures are recoverable
When it happens
Trigger: SendString of a Unicode character when the desktop is locked/secure, UIPI blocks injection after the first event, or input is disabled mid-send — the down lands but the up does not, and the recovery up also fails.
Common situations: Text automation racing a screen lock or UAC elevation prompt; sending to an elevated app from a non-elevated process; RDP disconnecting between the pair's two events.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- SendInput inserted of events (Win32 error )
- config lock path contains invalid Unicode and cannot be…
- credential path contains invalid Unicode and cannot be…
- strategy " " is macOS-only; this backend dispatches…
- terminal host window no longer exists
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/690a21e08a2ec0c0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/win32.mjs:63
throw new InputDeliveryException(sent, inputs.Length, error);
}
}
public static void SendKey(ushort vk, uint flags) {
SendChecked(new INPUT[] { KeyInput(vk, 0, flags) });
}
public static void SendString(string text) {
// UTF-16 code units, including both halves of surrogate pairs. UNICODE
// requires wVk=0 and may only be combined with KEYUP, never SCANCODE.
foreach (char c in text) {
INPUT up = KeyInput(0, c, UNICODE | KEYUP);
try { SendChecked(new INPUT[] { KeyInput(0, c, UNICODE), up }); }
catch (InputDeliveryException failure) {
// A partial pair may leave only our down event inserted. Release it
// once, never replay text, and still report the original failure.
if (failure.Inserted == 1) {
try { SendChecked(new INPUT[] { up }); }
catch (Exception cleanup) {
throw new AggregateException("Unicode input failed: " + failure.Message + "; key-up recovery failed: " + cleanup.Message, failure, cleanup);
}
}
throw;
}
}
}
}`;
function recordingsDir() {
return process.env.CODEWHALE_CU_RECORDINGS_DIR || path.join(os.homedir(), ".codewhale-cu", "recordings");
}
// Windows virtual-key codes for named keys.
const VK = {
return: 0x0d, enter: 0x0d, tab: 0x09, escape: 0x1b, esc: 0x1b, space: 0x20,
backspace: 0x08, delete: 0x2e, home: 0x24, end: 0x23, pageup: 0x21, pagedown: 0x22,
left: 0x25, up: 0x26, right: 0x27, down: 0x28, capslock: 0x14, insert: 0x2d,
f1: 0x70, f2: 0x71, f3: 0x72, f4: 0x73, f5: 0x74, f6: 0x75, f7: 0x76, f8: 0x77,View on GitHub (pinned to 73e0f67d83)