microsoft/typescript-go · error
failed to read changes
Error message
failed to read changes
What it means
Error raised when the ReadDirectoryChangesW call itself fails to arm in beginRead. It surfaces two ways: synchronously from WatchDirectory when the first read armed inside subscribe fails, or via fatal() (wrapped with ErrWatchTerminated by handleWatcherError) when the next read fails inside the run loop. The sentinel does not carry the underlying Win32 error; only the fixed text is available.
Source
Thrown at internal/fswatch/windows.go:107
// - FILE_ACTION_ADDED / RENAMED_NEW_NAME → events.create (→ EventUpdate)
// - FILE_ACTION_MODIFIED → events.update (→ EventUpdate)
// - FILE_ACTION_REMOVED / RENAMED_OLD_NAME → events.remove + tree.remove
// 4. Call dirWatch.notify() to trigger the debouncer.
//
// Error recovery:
// - ERROR_OPERATION_ABORTED → normal shutdown (CancelIoEx was called).
// - ERROR_INVALID_PARAMETER → shrink buffer to 64 KB (network share limit).
// - ERROR_NOTIFY_ENUM_DIR → ErrOverflow (too many changes queued).
// - ERROR_ACCESS_DENIED → check if the watched dir was deleted.
//
// Shutdown:
// close(stopCh) → CancelIoEx cancels in-flight IO → run() goroutine
// exits → deferred CloseHandle closes the directory handle → doneCh closed.
// ---------------------------------------------------------------------------
var (
errGetFileInfo = errors.New("could not get file information")
errReadChanges = errors.New("failed to read changes")
errGetOverlappedResult = errors.New("GetOverlappedResult failed")
errUnknown = errors.New("unknown error")
)
const (
defaultBufSize = 1024 * 1024
networkBufSize = 64 * 1024
notifyChangeFilter = windows.FILE_NOTIFY_CHANGE_FILE_NAME |
windows.FILE_NOTIFY_CHANGE_DIR_NAME |
windows.FILE_NOTIFY_CHANGE_SIZE |
windows.FILE_NOTIFY_CHANGE_LAST_WRITE
)
// windowsBackend.
type windowsBackend struct {
watcherBase
}View on GitHub (pinned to 1bcfa18d79)
Solutions
- If it arrives wrapped in ErrWatchTerminated, call Close() and re-subscribe once the directory is back
- For subscribe-time failures, verify the directory with os.Stat and retry with backoff
- Serialize watch lifecycle in your code: do not race Close() with a new WatchDirectory on the same path
- Report it upstream if it reproduces against a stable local directory
Defensive patterns
Strategy: try-catch
Try / catch
// subscribe-time:
if err != nil && err.Error() == "failed to read changes" {
// verify the directory, then retry with backoff
}
// run-time (via callback):
if errors.Is(err, fswatch.ErrWatchTerminated) {
// fatal read failure: Close and resubscribe when ready
} Prevention
- Do not race Close() against a new WatchDirectory on the same directory
- Serialize watch lifecycle transitions in your own wrapper
- Verify the directory exists and is local before subscribing
- Report reproducible failures against stable directories upstream
When it happens
Trigger: The overlapped ReadDirectoryChangesW call returns FALSE immediately: the directory handle became invalid (directory deleted, handle raced with Close), or the combination of parameters is unsupported for this filesystem/handle. Watch churn where Close and re-watch race on the same directory.
Common situations: Directories deleted during subscription. Network redirectors with parameter restrictions. Watch lifecycles torn down and recreated concurrently from multiple goroutines.
Related errors
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/1787e7e262f29e80.
Report an issue: GitHub.