microsoft/typescript-go · error
CreateEvent: %w
Error message
CreateEvent: %w
What it means
Error raised when CreateEvent fails while arming an overlapped ReadDirectoryChangesW request in beginRead; the %w wraps the Win32 error. On the first read (inside subscribe) it fails WatchDirectory synchronously; failures for later reads go through fatal() and reach the callback wrapped with ErrWatchTerminated. CreateEvent allocates a kernel event object, so failure in practice means kernel object or memory exhaustion.
Source
Thrown at internal/fswatch/windows.go:212
stopCh: make(chan struct{}),
doneCh: make(chan struct{}),
bufBytes: defaultBufSize,
}, nil
}
func (s *windowsSubscription) beginRead() (*windowsRead, error) {
s.mu.Lock()
if s.stopped {
s.mu.Unlock()
return nil, nil
}
bufSize := s.bufBytes
s.mu.Unlock()
req := &windowsRead{buf: make([]byte, bufSize)}
ev, err := windows.CreateEvent(nil, 1, 0, nil)
if err != nil {
return nil, fmt.Errorf("CreateEvent: %w", err)
}
req.event = ev
req.overlapped.HEvent = ev
var bytesReturned uint32
err = windows.ReadDirectoryChanges(
s.handle,
&req.buf[0],
uint32(len(req.buf)),
s.dirWatch.recursive, // recursive
notifyChangeFilter,
&bytesReturned,
&req.overlapped,
0,
)
if err != nil {
_ = windows.CloseHandle(ev)
return nil, &dirWatchError{err: errReadChanges, dirWatch: s.dirWatch}View on GitHub (pinned to 1bcfa18d79)
Solutions
- Reduce simultaneous watches: consolidate sibling directories into one recursive WithRecursive watch
- Find and fix handle leaks in the process (watch handle count in Task Manager or Process Explorer)
- Retry with backoff: transient exhaustion clears as other handles close
- If delivered as ErrWatchTerminated, call Close() and re-subscribe after freeing handles
Defensive patterns
Strategy: retry
Validate before calling
// Cap concurrent watches; consolidate where possible:
// one recursive watch instead of N per-child watches
if activeWatches >= maxWatches {
return errors.New("watch budget exceeded")
} Try / catch
// subscribe-time:
if err != nil && strings.Contains(err.Error(), "CreateEvent") {
// kernel object exhaustion: close idle handles, then retry with backoff
}
// run-time (via callback):
if errors.Is(err, fswatch.ErrWatchTerminated) {
watch.Close()
go resubscribeAfterFreedHandles(dir)
} Prevention
- Track handle count in long-running processes; leak-detector alerts before CreateEvent fails
- Consolidate sibling watches into recursive watches to cut kernel objects
- Retry with backoff: transient exhaustion clears when handles close
- Close watches as soon as they are no longer needed
When it happens
Trigger: Process or system handle limits reached: thousands of concurrent watches each create event objects, or other code in the process leaks handles. Paged pool exhaustion under heavy pressure.
Common situations: Servers watching thousands of directories with one subscription each. Programs leaking handles over long uptimes until CreateEvent fails. Watch churn that outpaces kernel object cleanup.
Related errors
- GetOverlappedResult failed
- Child process exited with code ${this.child.exitCode} before
- SyncRpcChannel: timed out connecting to named pipe
- error opening directory: %w
- fswatch: failed to watch directory %q: %w
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/08e1e6533d032216.
Report an issue: GitHub.