gitbutlerapp/gitbutler · warning

Failed to stop project watcher for ${projectId}

Error message

Failed to stop project watcher for ${projectId}

What it means

stopAllWatchersForShutdown() iterates every project watcher at quit and calls handle.stop(); each failure is individually caught and warned with the projectId so one bad stop cannot block the rest. Maps are cleared unconditionally afterward, and the function returns how many subscriptions existed.

Source

Thrown at apps/lite/electron/src/watcher.ts:240

				// Once the creation has been fulfilled, remove it from the pending map.
				this.pendingProjectWatchers.delete(projectId);
			});

		// While the watcher is being created, store it in the pending watchers,
		// so that we can avoid creating multiple handles for the same project.
		this.pendingProjectWatchers.set(projectId, creation);
		return creation;
	}

	stopAllWatchersForShutdown(): number {
		const stopped = this.watcherSubscriptions.size;

		for (const [projectId, projectWatcher] of this.projectWatchers) {
			try {
				projectWatcher.handle.stop();
			} catch (error) {
				// oxlint-disable-next-line no-console
				console.warn(`Failed to stop project watcher for ${projectId}`, error);
			}
		}

		this.pendingProjectWatchers.clear();
		this.projectWatchers.clear();
		this.watcherSubscriptions.clear();
		this.senderSubscriptions.clear();

		return stopped;
	}

	/**
	 * Setup a listener that removes all subscriptions for a given sender on it's destruction.
	 *
	 * Here we ensure that on the closing of a window, all subscriptions associated are closed.
	 */
	private registerSenderCleanup(sender: Electron.WebContents): void {
		const senderId = sender.id;

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Usually ignorable at quit — the process is about to exit anyway
  2. Call destroy() early in the quit sequence, before windows are destroyed, so stop IPC still has a live channel
  3. Ensure the backend terminates watchers on client disconnect as a safety net
  4. Capture the payload and file an issue if it fires frequently
Defensive patterns

Strategy: try-catch

Try / catch

for (const [projectId, projectWatcher] of this.projectWatchers) {
	try {
		projectWatcher.handle.stop();
	} catch (error) {
		console.warn(`Failed to stop project watcher for ${projectId}`, error);
	}
}

Prevention

When it happens

Trigger: Quitting the Lite app (destroy() leading to stopAllWatchersForShutdown at apps/lite/electron/src/watcher.ts:240) while any handle.stop() IPC fails — the backend already exited, Electron is tearing down IPC, or a watcher was invalidated by an earlier error.

Common situations: App quit with active project watchers; a crashed backend process; slow shutdown where the event loop drains before IPC replies arrive.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/899867d1d515842b. Report an issue: GitHub.