Hmbown/CodeWhale · error · InputDeliveryException
SendInput inserted of events (Win32 error )
Error message
SendInput inserted {0} of {1} events (Win32 error {2}) What it means
The Win32 helper SendChecked calls the native SendInput API and verifies it inserted all submitted events. If SendInput reports fewer events than were passed in, it throws InputDeliveryException with the inserted/expected counts and the Win32 error code. This detects partially applied input streams rather than letting the caller assume all keystrokes landed.
Solutions
- Run the automation in the same interactive, elevated (or higher) session as the target window — check the Win32 error in the message (usually 5 = access denied)
- Unlock the screen / connect the RDP session (shadow session) before sending input
- Retry SendChecked for transient failures, and split large INPUT arrays into smaller batches
- If injecting into elevated UI, run your host process elevated or adjust UIPI (change window integrity only if you own the policy)
Example fix
// before
SendKey(vk, flags);
// after
try { SendKey(vk, flags); }
catch (InputDeliveryException e) {
if (e.Inserted == 1) SendChecked(new INPUT[] { up }); // release partial key-down
throw;
} Defensive patterns
Strategy: try-catch
Try / catch
try { SendChecked(inputs); }
catch (InputDeliveryException e) {
if (e.Inserted == 1) { /* release the single inserted event */ }
if ((uint)e.Data["Win32Error"] == 5) throw new InvalidOperationException("input blocked: run elevated / interactive", e);
throw;
} Prevention
- Keep the automation process in the interactive, unlocked desktop session
- Match elevation level with the target window (UIPI)
- Keep RDP sessions connected (or shadow them) during input injection
- Batch inputs and verify counts after each batch
When it happens
Trigger: Any input injection (SendKey/SendString/pointer events) when the desktop or window station is not interactive (locked screen, secure desktop, UAC prompt, disconnected RDP session), or when another process with higher privileges blocks injection (UIPI).
Common situations: Running the automation from a service or scheduler session; screen locked during a run; trying to send input to an elevated window from a non-elevated process; Win32 error 5 (access denied) or 0 mapping to unexpected states.
Related errors
- terminal host window no longer exists
- terminal host window owner changed
- terminal maximize request was rejected
- terminal restore request was rejected
- terminal restore was not observed before the deadline
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/cb1ccc66627f3906.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/win32.mjs:45
[StructLayout(LayoutKind.Sequential)] public struct INPUT { public uint type; public INPUTUNION u; }
public const uint MOVED = 0x0001, LEFTDOWN = 0x0002, LEFTUP = 0x0004, RIGHTDOWN = 0x0008, RIGHTUP = 0x0010,
MIDDLEDOWN = 0x0020, MIDDLEUP = 0x0040, WHEEL = 0x0800, HWHEEL = 0x1000, ABSOLUTE = 0x8000, VIRTUALKEY = 0x4000, KEYUP = 0x0002, UNICODE = 0x0004;
public static INPUT MouseInput(uint flags, int x, int y, uint data) {
return new INPUT { type = 0, u = new INPUTUNION { mi = new MOUSEINPUT { dx = x, dy = y, mouseData = data, dwFlags = flags, time = 0, dwExtraInfo = IntPtr.Zero } } };
}
public static INPUT KeyInput(ushort vk, ushort scan, uint flags) {
return new INPUT { type = 1, u = new INPUTUNION { ki = new KEYBDINPUT { wVk = vk, wScan = scan, dwFlags = flags, time = 0, dwExtraInfo = IntPtr.Zero } } };
}
public sealed class InputDeliveryException : InvalidOperationException {
public readonly uint Inserted;
public InputDeliveryException(uint inserted, int expected, int error)
: base(String.Format("SendInput inserted {0} of {1} events (Win32 error {2})", inserted, expected, error)) { Inserted = inserted; }
}
public static void SendChecked(INPUT[] inputs) {
uint sent = SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
if (sent != (uint)inputs.Length) {
int error = Marshal.GetLastWin32Error();
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);View on GitHub (pinned to 73e0f67d83)