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

  1. Gate the renderer call on the main-process 'ready' event and on a 'mainWindow-ready' IPC handshake.
  2. Ensure watcher is constructed in app.whenReady() before any window loads.
  3. On re-open after close, re-create the watcher rather than reusing a disposed instance.
  4. 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

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


AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13). Data as JSON: /api/errors/b674bd61ccc952ab. Report an issue: GitHub.