{"record":{"id":"93dd05dd1c2832d8","repo":"usebruno/bruno","slug":"collection-location-does-not-exist","errorCode":null,"errorMessage":"Collection location does not exist","messagePattern":"Collection location does not exist","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-electron/src/ipc/collection.js","lineNumber":2676,"sourceCode":"        (name) =>\n          name === 'bruno.json'\n          || name === 'opencollection.yml'\n          || /^[^/]+\\/bruno\\.json$/.test(name)\n          || /^[^/]+\\/opencollection\\.yml$/.test(name)\n      );\n    } catch {\n      return false;\n    }\n  });\n\n  ipcMain.handle('renderer:import-collection-zip', async (event, zipFilePath, collectionLocation) => {\n    try {\n      if (!fs.existsSync(zipFilePath)) {\n        throw new Error('ZIP file does not exist');\n      }\n\n      if (!collectionLocation || !fs.existsSync(collectionLocation)) {\n        throw new Error('Collection location does not exist');\n      }\n\n      const tempDir = path.join(os.tmpdir(), `bruno_zip_import_${Date.now()}`);\n      await fsExtra.ensureDir(tempDir);\n\n      // Validates that no symlinks point outside the base directory\n      const validateNoExternalSymlinks = (dir, baseDir) => {\n        const entries = fs.readdirSync(dir, { withFileTypes: true });\n        for (const entry of entries) {\n          const fullPath = path.join(dir, entry.name);\n          const stat = fs.lstatSync(fullPath);\n\n          if (stat.isSymbolicLink()) {\n            const linkTarget = fs.readlinkSync(fullPath);\n            const resolvedTarget = path.resolve(path.dirname(fullPath), linkTarget);\n            if (!resolvedTarget.startsWith(baseDir + path.sep) && resolvedTarget !== baseDir) {\n              throw new Error(`Security error: Symlink \"${entry.name}\" points outside extraction directory`);\n            }","sourceCodeStart":2658,"sourceCodeEnd":2694,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-electron/src/ipc/collection.js#L2658-L2694","documentation":"renderer:import-collection-zip validates collectionLocation (the destination directory) is truthy and exists on disk. Throws before creating the extraction temp dir, preventing import into a missing target.","triggerScenarios":"Calling renderer:import-collection-zip with a collectionLocation that is empty or not present on disk.","commonSituations":"User-selected import destination deleted between selection and confirmation; removable media unmounted; path typed manually and incorrect.","solutions":["Pick an existing directory as the import destination.","Create the destination directory (fs.mkdirSync recursive) before invoking.","Default to a known-writable location (e.g. the workspace root) when none is chosen."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const fs = require('fs');\nif (!collectionLocation || !fs.existsSync(collectionLocation)) {\n  fs.mkdirSync(collectionLocation, { recursive: true }); // or re-prompt\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ipcRenderer.invoke('renderer:import-collection-zip', zipFilePath, collectionLocation);\n} catch (err) {\n  if (/Collection location does not exist/.test(err.message)) {\n    // re-prompt the user to pick a valid destination\n  } else {\n    throw err;\n  }\n}","preventionTips":["Default to a known-writable workspace location when none is chosen.","Validate the destination directory exists at click time."],"tags":["ipc","import","zip","filesystem","validation"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}