{"record":{"id":"d9897b8fc35790cd","repo":"usebruno/bruno","slug":"environment-envfilepath-does-not-exist","errorCode":null,"errorMessage":"environment: ${envFilePath} does not exist","messagePattern":"environment: (.+?) does not exist","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-electron/src/ipc/collection.js","lineNumber":790,"sourceCode":"      await writeFile(envFilePath, content);\n    } catch (error) {\n      return Promise.reject(error);\n    }\n  });\n\n  // save environment\n  ipcMain.handle('renderer:save-environment', async (event, collectionPathname, environment) => {\n    try {\n      const format = getCollectionFormat(collectionPathname);\n      const envFilePath = resolveEnvironmentFilePath(collectionPathname, environment.name, format);\n\n      const envDirPath = path.dirname(envFilePath);\n      if (!fs.existsSync(envDirPath)) {\n        await createDirectory(envDirPath);\n      }\n\n      if (!fs.existsSync(envFilePath)) {\n        throw new Error(`environment: ${envFilePath} does not exist`);\n      }\n\n      // Serialize concurrent saves to the same env file. Without the lock the\n      // read-then-write pattern below can interleave: writer A reads pre-A state,\n      // writer B reads pre-A state, B writes B-content, A writes A-content —\n      // dropping B's update. Rapid scripted `bru.setEnvVar(..., {persist:true})`\n      // calls (e.g. across folder-run requests) hit this without serialization.\n      await withFileLock(envFilePath, async () => {\n        if (envHasSecrets(environment)) {\n          environmentSecretsStore.storeEnvSecrets(collectionPathname, environment);\n        }\n\n        const content = await stringifyEnvironment(environment, { format });\n        const existing = fs.readFileSync(envFilePath, 'utf8');\n        if (content === existing) return; // skip write if content unchanged\n        await writeFile(envFilePath, content);\n      });\n    } catch (error) {","sourceCodeStart":772,"sourceCodeEnd":808,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-electron/src/ipc/collection.js#L772-L808","documentation":"Thrown by 'renderer:save-environment' when the resolved environment file does not exist. Notable behavior: the handler first ensures the environments directory exists (creating it if needed) but then REQUIRES the environment file itself to already exist — save-environment overwrites, it does not create a new environment file. The subsequent read-then-write is serialized with a file lock to prevent lost updates from concurrent bru.setEnvVar persist calls.","triggerScenarios":"Calling save-environment for an environment that was never created, was deleted, or whose name is misspelled. Saving 'Local' or another env that has no file yet. Race where another process deletes the env file between resolve and the existence check.","commonSituations":"UI allows editing an env that has no backing file. A collection imported from elsewhere missing the environments folder files. Name casing mismatch on case-sensitive filesystems.","solutions":["Create the environment first via the create-environment flow, then call save-environment.","Verify envFilePath exists (or that the environment name is in the collection's bruno.json environment list) before saving.","If the environments directory was recreated but files are missing, re-initialize the environment files from the config."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const envFile = await window.ipcRenderer.invoke('renderer:resolve-environment-file-path', collectionPathname, environment.name, format);\nconst exists = await window.ipcRenderer.invoke('renderer:file-exists', envFile);\nif (!exists) {\n  // create the environment first, then save\n}","typeGuard":null,"tryCatchPattern":"try {\n  await window.ipcRenderer.invoke('renderer:save-environment', collectionPathname, environment);\n} catch (e) {\n  if (/environment:.+does not exist/.test(e.message)) {\n    await window.ipcRenderer.invoke('renderer:create-environment', collectionPathname, environment);\n    await window.ipcRenderer.invoke('renderer:save-environment', collectionPathname, environment);\n  } else throw e;\n}","preventionTips":["Remember save-environment overwrites only; always create the environment file first.","Keep the bruno.json environment list and the environments/ files in sync.","For scripted bru.setEnvVar persist calls, ensure the env file exists before the first write."],"tags":["ipc","filesystem","environment","bruno"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}