usebruno/bruno · warning · Error
Invalid package name(s): ${invalid.join(', ')}
Error message
Invalid package name(s): ${invalid.join(', ')} What it means
renderer:install-postman-packages filters package names against NPM_NAME_REGEX `/^(?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*$/i` (utils/install-packages.js:5). Any name that fails is collected and joined into the error message. The regex enforces npm's scoped/unscoped naming rules.
Source
Thrown at packages/bruno-electron/src/ipc/collection.js:2450
console.error('Error converting Postman to Bruno:', error);
return Promise.reject(error);
}
});
ipcMain.handle('renderer:install-postman-packages', async (_event, collectionPathname, packages) => {
if (typeof collectionPathname !== 'string' || !collectionPathname) {
throw new Error('collectionPathname is required');
}
if (!Array.isArray(packages) || packages.length === 0) {
throw new Error('packages must be a non-empty array');
}
if (!fs.existsSync(collectionPathname) || !fs.statSync(collectionPathname).isDirectory()) {
throw new Error(`Collection path does not exist: ${collectionPathname}`);
}
const invalid = packages.filter((p) => !isValidNpmPackageName(p));
if (invalid.length > 0) {
throw new Error(`Invalid package name(s): ${invalid.join(', ')}`);
}
await waitForShellEnv();
return runNpmInstall({ collectionPath: collectionPathname, packages });
});
ipcMain.handle('renderer:get-collection-json', async (event, collectionPath) => {
let variables = {};
let name = '';
const getBruFilesRecursively = async (dir) => {
const getFilesInOrder = async (dir) => {
let bruJsons = [];
const traverse = async (currentPath) => {
const filesInCurrentDir = fs.readdirSync(currentPath);
if (currentPath.includes('node_modules')) {
return;View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Strip version specifiers and paths from each name before passing (use the bare package name).
- Lowercase scope names (`@Scope/pkg` -> `@scope/pkg`).
- Validate each name client-side with the same regex before invoking the IPC.
Example fix
// before
ipcRenderer.invoke('renderer:install-postman-packages', dir, ['axios@1.2.3', 'Lodash']);
// after
const NPM_NAME = /^(?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*$/i;
const clean = ['axios', 'lodash'].filter((n) => NPM_NAME.test(n));
ipcRenderer.invoke('renderer:install-postman-packages', dir, clean); Defensive patterns
Strategy: validation
Validate before calling
const NPM_NAME = /^(?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*$/i;
const invalid = packages.filter((p) => !NPM_NAME.test(p));
if (invalid.length) {
throw new Error(`Invalid package name(s): ${invalid.join(', ')}`);
} Type guard
const NPM_NAME = /^(?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*$/i;
/** @param {unknown} p @returns {p is string} */
function isValidPackageName(p) {
return typeof p === 'string' && NPM_NAME.test(p);
} Prevention
- Strip version specifiers (`pkg@1.2.3` -> `pkg`) and subpaths before passing.
- Lowercase scope names; reject names containing spaces or leading underscores.
- Validate with the same regex on the renderer side for an early, friendly error.
When it happens
Trigger: Passing a packages array containing any string with invalid npm name syntax — uppercase scope characters, leading punctuation/underscore, spaces, slashes in unscoped names, etc.
Common situations: Postman pre-request scripts reference packages with non-npm syntax (e.g. `lodash-es/feat`, `_private`, `My Pkg`); typos; version suffixes accidentally included (`axios@1.2.3`).
Related errors
- packages must be a non-empty array
- Collection path does not exist: ${collectionPathname}
- collectionPathname is required
- Export location does not exist
- Invalid file name
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/1c1f81b23383ecb0.
Report an issue: GitHub.