{"record":{"id":"1c1f81b23383ecb0","repo":"usebruno/bruno","slug":"invalid-package-name-s-invalid-join","errorCode":null,"errorMessage":"Invalid package name(s): ${invalid.join(', ')}","messagePattern":"Invalid package name\\(s\\): (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/bruno-electron/src/ipc/collection.js","lineNumber":2450,"sourceCode":"      console.error('Error converting Postman to Bruno:', error);\n      return Promise.reject(error);\n    }\n  });\n\n  ipcMain.handle('renderer:install-postman-packages', async (_event, collectionPathname, packages) => {\n    if (typeof collectionPathname !== 'string' || !collectionPathname) {\n      throw new Error('collectionPathname is required');\n    }\n    if (!Array.isArray(packages) || packages.length === 0) {\n      throw new Error('packages must be a non-empty array');\n    }\n    if (!fs.existsSync(collectionPathname) || !fs.statSync(collectionPathname).isDirectory()) {\n      throw new Error(`Collection path does not exist: ${collectionPathname}`);\n    }\n\n    const invalid = packages.filter((p) => !isValidNpmPackageName(p));\n    if (invalid.length > 0) {\n      throw new Error(`Invalid package name(s): ${invalid.join(', ')}`);\n    }\n\n    await waitForShellEnv();\n    return runNpmInstall({ collectionPath: collectionPathname, packages });\n  });\n\n  ipcMain.handle('renderer:get-collection-json', async (event, collectionPath) => {\n    let variables = {};\n    let name = '';\n    const getBruFilesRecursively = async (dir) => {\n      const getFilesInOrder = async (dir) => {\n        let bruJsons = [];\n\n        const traverse = async (currentPath) => {\n          const filesInCurrentDir = fs.readdirSync(currentPath);\n\n          if (currentPath.includes('node_modules')) {\n            return;","sourceCodeStart":2432,"sourceCodeEnd":2468,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-electron/src/ipc/collection.js#L2432-L2468","documentation":"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.","triggerScenarios":"Passing a packages array containing any string with invalid npm name syntax — uppercase scope characters, leading punctuation/underscore, spaces, slashes in unscoped names, etc.","commonSituations":"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`).","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."],"exampleFix":"// before\nipcRenderer.invoke('renderer:install-postman-packages', dir, ['axios@1.2.3', 'Lodash']);\n\n// after\nconst NPM_NAME = /^(?:@[a-z0-9][\\w.-]*\\/)?[a-z0-9][\\w.-]*$/i;\nconst clean = ['axios', 'lodash'].filter((n) => NPM_NAME.test(n));\nipcRenderer.invoke('renderer:install-postman-packages', dir, clean);","handlingStrategy":"validation","validationCode":"const NPM_NAME = /^(?:@[a-z0-9][\\w.-]*\\/)?[a-z0-9][\\w.-]*$/i;\nconst invalid = packages.filter((p) => !NPM_NAME.test(p));\nif (invalid.length) {\n  throw new Error(`Invalid package name(s): ${invalid.join(', ')}`);\n}","typeGuard":"const NPM_NAME = /^(?:@[a-z0-9][\\w.-]*\\/)?[a-z0-9][\\w.-]*$/i;\n/** @param {unknown} p @returns {p is string} */\nfunction isValidPackageName(p) {\n  return typeof p === 'string' && NPM_NAME.test(p);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["ipc","postman","npm","validation","regex","package-name"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}