usebruno/bruno · error · Error
Watcher or mainWindow not available
Error message
Watcher or mainWindow not available
What it means
The renderer:add-collection-watcher handler requires both the module-level `watcher` (file system watcher instance) and `mainWindow` (Electron BrowserWindow) to be initialized before it can wire up notifications. The check runs before any try/catch, so the error propagates directly to the renderer.
Source
Thrown at packages/bruno-electron/src/ipc/collection.js:2345
await writeFile(path.join(tempDirectoryPath, 'opencollection.yml'), content);
const metadata = {
workspaceUid,
workspacePath,
type: 'scratch'
};
fs.writeFileSync(path.join(tempDirectoryPath, 'metadata.json'), JSON.stringify(metadata));
return tempDirectoryPath;
} catch (error) {
console.error('Error mounting workspace scratch collection:', error);
throw error;
}
});
ipcMain.handle('renderer:add-collection-watcher', async (event, { collectionPath, collectionUid, brunoConfig }) => {
if (!watcher || !mainWindow) {
throw new Error('Watcher or mainWindow not available');
}
try {
const { size, filesCount, maxFileSize } = await getCollectionStats(collectionPath);
const shouldLoadCollectionAsync
= (size > MAX_COLLECTION_SIZE_IN_MB)
|| (filesCount > MAX_COLLECTION_FILES_COUNT)
|| (maxFileSize > MAX_SINGLE_FILE_SIZE_IN_COLLECTION_IN_MB);
watcher.addWatcher(mainWindow, collectionPath, collectionUid, brunoConfig, false, shouldLoadCollectionAsync);
return { success: true };
} catch (error) {
console.error('Error adding collection watcher:', error);
throw error;
}
});View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Gate the renderer call on the main-process 'ready' event and on a 'mainWindow-ready' IPC handshake.
- Ensure watcher is constructed in app.whenReady() before any window loads.
- On re-open after close, re-create the watcher rather than reusing a disposed instance.
- Log watcher/mainWindow init failures at boot so silent null states surface.
Defensive patterns
Strategy: validation
Validate before calling
// renderer-side: only call after the main process signals readiness
if (!window.__BRUNO_MAIN_READY__) {
console.warn('Deferring add-collection-watcher: main process not ready');
return;
}
ipcRenderer.invoke('renderer:add-collection-watcher', { collectionPath, collectionUid, brunoConfig }); Try / catch
try {
await ipcRenderer.invoke('renderer:add-collection-watcher', payload);
} catch (err) {
if (/Watcher or mainWindow not available/.test(err.message)) {
// back off and retry once after app-ready, do not spam
} else {
throw err;
}
} Prevention
- Construct the watcher inside app.whenReady() and expose a ready handshake to the renderer.
- Tear down IPC callers before nulling mainWindow during shutdown.
- Log watcher initialization failures at boot so silent null states surface early.
When it happens
Trigger: Calling renderer:add-collection-watcher before app 'ready' has fired, before mainWindow is created, after the watcher has been disposed, or during shutdown when mainWindow is null.
Common situations: Startup race where the renderer fires the IPC during its mount before the main process finished wiring the watcher; shutdown sequence where the window was closed but the renderer is still alive; watcher initialization failed silently at boot.
Related errors
- Could not reach the mock server
- path: ${pathname} does not exist
- ${filename} file does not exist
- Export path must be an absolute directory path
- Export path: ${filePath} is not an existing directory
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/b674bd61ccc952ab.
Report an issue: GitHub.