Awesome Reviewers

When an interaction or startup path can fail (or an expected event never arrives), make error handling deterministic and user-safe: clean up reliably, reuse the same validation+error messaging, recover on the right signal, and replace (not just cover) UI that could trap focus.

Apply this checklist: 1) Deterministic cleanup for missing events

Example pattern:

function startDrag({ clientY }: { clientY: number }) {
  const startHeight = height;
  const previousCursor = document.body.style.cursor;
  const previousUserSelect = document.body.style.userSelect;
  document.body.style.cursor = 'row-resize';
  document.body.style.userSelect = 'none';

  const end = () => {
    document.body.style.cursor = previousCursor;
    document.body.style.userSelect = previousUserSelect;
    window.removeEventListener('pointermove', onMove);
    window.removeEventListener('pointerup', end);
    window.removeEventListener('pointercancel', end);
  };

  const onMove = (move: PointerEvent) => {
    // Cover edge cases: release outside window may skip pointerup.
    if ((move.buttons ?? 0) === 0) return end();
    onHeightChange(clampTerminalPanelHeight(startHeight + (clientY - move.clientY), window.innerHeight));
  };

  window.addEventListener('pointermove', onMove);
  window.addEventListener('pointerup', end);
  window.addEventListener('pointercancel', end);
}

2) Reuse the same “can send/can’t send” checks on every action path

3) Retry startup/environment lookups on the real recovery boundary

4) On later failures, replace the UI state to prevent trapping