usebruno/bruno · error · Error

Export path must be an absolute directory path

Error message

Export path must be an absolute directory path

What it means

Thrown by 'renderer:export-environment' when the supplied filePath is falsy, not a string, or fails path.isAbsolute(). Bruno requires the export destination to be an absolute, user-chosen directory (typically from a native dialog.showOpenDialog result). Relative paths, undefined, or null all trip this guard before any disk access.

Source

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

      }

      await withFileLock(envFilePath, async () => {
        const fileContent = fs.readFileSync(envFilePath, 'utf8');
        const environment = parseEnvironment(fileContent, { format });
        environment.color = color;
        const updatedContent = stringifyEnvironment(environment, { format });
        await writeFile(envFilePath, updatedContent);
      });
    } catch (error) {
      return Promise.reject(error);
    }
  });

  // Generic environment export handler
  ipcMain.handle('renderer:export-environment', async (event, { environments, environmentType, filePath, exportFormat = 'folder' }) => {
    try {
      if (!filePath || typeof filePath !== 'string' || !path.isAbsolute(filePath)) {
        throw new Error('Export path must be an absolute directory path');
      }
      if (!fs.existsSync(filePath) || !isDirectory(filePath)) {
        throw new Error(`Export path: ${filePath} is not an existing directory`);
      }
      if (environmentType !== 'collection' && environmentType !== 'global') {
        throw new Error(`Unsupported environment type: ${environmentType}`);
      }

      const { app } = require('electron');
      const appVersion = app?.getVersion() || '2.0.0';

      // For single environments and folder exports, include info in each environment
      const environmentWithInfo = (environment) => ({
        name: environment.name,
        variables: environment.variables,
        color: environment.color ?? undefined,
        info: {
          type: 'bruno-environment',

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Gate the export on a non-empty absolute path returned by the folder picker; abort the action when the user cancels.
  2. Normalize user input with path.resolve() only after confirming a value exists, or require the picker result.
  3. Add a type check in the renderer payload before invoking the IPC.

Example fix

// before
await window.Ipc.invoke('renderer:export-environment', { environments, environmentType, filePath: inputRef.current.value });

// after
const filePath = await window.ipc.invoke('main:select-folder');
if (!filePath) return; // user cancelled
await window.Ipc.invoke('renderer:export-environment', { environments, environmentType, filePath });
Defensive patterns

Strategy: validation

Validate before calling

function isValidExportPath(p: unknown): boolean {
  return typeof p === 'string' && p.length > 0 && path.isAbsolute(p);
}
if (!isValidExportPath(filePath)) {
  throw new Error('An absolute export directory is required');
}

Type guard

function isAbsoluteDirPath(p: unknown): p is string {
  return typeof p === 'string' && p.length > 0 && path.isAbsolute(p);
}

Try / catch

try {
  await window.Ipc.invoke('renderer:export-environment', payload);
} catch (e) {
  if (String(e?.message).includes('absolute directory path')) {
    const picked = await pickFolder(); if (!picked) return;
    payload.filePath = picked;
    await window.Ipc.invoke('renderer:export-environment', payload);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling export-environment with filePath omitted from the payload, passed as a relative path like '../exports', or passed as a non-string (number/object). Common when the user cancels the folder picker and the dialog returns undefined/empty string but the export call still fires.

Common situations: Folder-picker dialog cancelled or not shown, hardcoded relative path in test/script, path stored in state as undefined after a navigation.

Related errors


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