usebruno/bruno · error · Error

Could not determine collection for target directory

Error message

Could not determine collection for target directory

What it means

Thrown by 'renderer:save-transient-request' when findCollectionPathByItemPath(targetDirname) returns null. That helper walks every path registered with the collection watcher (sorted deepest-first) and returns the first whose normalized form is an ancestor of the target. Null means targetDirname is not inside any open/watched collection.

Source

Thrown at packages/bruno-electron/src/ipc/collection.js:598

      return Promise.reject(error);
    }
  });

  ipcMain.handle('renderer:save-transient-request', async (event, { sourcePathname, targetDirname, targetFilename, request, format, sourceFormat }) => {
    try {
      if (!fs.existsSync(sourcePathname)) {
        throw new Error(`Source path: ${sourcePathname} does not exist`);
      }

      if (!fs.existsSync(targetDirname)) {
        throw new Error(`Target directory: ${targetDirname} does not exist`);
      }

      validatePathIsInsideCollection(targetDirname);

      const collectionPath = findCollectionPathByItemPath(targetDirname);
      if (!collectionPath) {
        throw new Error('Could not determine collection for target directory');
      }
      const targetFormat = getCollectionFormat(collectionPath);

      const filename = targetFilename || path.basename(sourcePathname);
      const filenameWithoutExt = filename.replace(/\.(bru|yml)$/, '');
      const finalFilename = `${filenameWithoutExt}.${targetFormat}`;
      const targetPathname = path.join(targetDirname, finalFilename);

      if (fs.existsSync(targetPathname)) {
        throw new Error(`A file with the name "${finalFilename}" already exists in the target location`);
      }

      const actualSourceFormat = sourceFormat || 'yml';
      const needsConversion = actualSourceFormat !== targetFormat;

      let finalContent;
      if (needsConversion) {
        const { parseRequest, stringifyRequest } = require('@usebruno/filestore');

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Ensure the collection containing targetDirname is opened and registered with the watcher before saving.
  2. Pass a targetDirname that is genuinely inside an open collection root.
  3. Normalize path separators (path.normalize) on the caller side to match the watcher's stored form.
  4. If using WSL, resolve the path to the same representation Bruno uses for the collection root.
Defensive patterns

Strategy: validation

Validate before calling

const collectionPath = await window.ipcRenderer.invoke('renderer:resolve-collection-for-path', targetDirname);
if (!collectionPath) {
  // open the collection containing targetDirname first, or pick a target inside an open collection
}

Try / catch

try {
  await window.ipcRenderer.invoke('renderer:save-transient-request', payload);
} catch (e) {
  if (/Could not determine collection/.test(e.message)) {
    await window.ipcRenderer.invoke('renderer:open-collection', pathToCollectionRoot);
    await window.ipcRenderer.invoke('renderer:save-transient-request', payload);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a targetDirname outside the collection root (absolute path to another drive, temp dir, or sibling directory). Saving into a collection that was closed/removed from the watcher. Path casing/separator differences on Windows/WSL that defeat the startsWith check.

Common situations: Target directory lives in a scratch/temp area not opened as a collection. Collection was closed in another window. WSL2 vs Windows path mismatch (e.g. /mnt/c vs C:\).

Related errors


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