{"record":{"id":"60289650b934fa52","repo":"usebruno/bruno","slug":"invalid-file-format-please-select-a-valid-openapi","errorCode":null,"errorMessage":"Invalid file format. Please select a valid OpenAPI spec in YAML or JSON format.","messagePattern":"Invalid file format\\. Please select a valid OpenAPI spec in YAML or JSON format\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/bruno-electron/src/app/apiSpecs.js","lineNumber":23,"sourceCode":"const { generateUidBasedOnHash } = require('../utils/common');\nconst { parseApiSpecContent } = require('../utils/apiSpecs');\nconst {\n  addApiSpecToWorkspace,\n  readWorkspaceConfig,\n  getWorkspaceUid\n} = require('../utils/workspace-config');\n\nconst DEFAULT_WORKSPACE_NAME = 'My Workspace';\n\nconst INVALID_EXTENSION_MESSAGE\n  = 'Invalid file format. Please select a valid OpenAPI spec in YAML or JSON format.';\n\nconst VALID_API_SPEC_EXTENSIONS = ['.yaml', '.yml', '.json'];\n\nconst validateApiSpec = (filePath) => {\n  const ext = path.extname(filePath).toLowerCase();\n  if (!VALID_API_SPEC_EXTENSIONS.includes(ext)) {\n    throw new Error(INVALID_EXTENSION_MESSAGE);\n  }\n};\n\nconst prepareWorkspaceConfigForClient = (workspaceConfig, isDefault) => {\n  if (isDefault) {\n    return {\n      ...workspaceConfig,\n      name: DEFAULT_WORKSPACE_NAME,\n      type: 'default'\n    };\n  }\n  return workspaceConfig;\n};\n\nconst openApiSpecDialog = async (win, watcher, options = {}) => {\n  const { filePaths } = await dialog.showOpenDialog(win, {\n    properties: ['openFile', 'createFile'],\n    filters: [{ name: 'OpenAPI Spec', extensions: ['yaml', 'yml', 'json'] }]","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-electron/src/app/apiSpecs.js#L5-L41","documentation":"Thrown by validateApiSpec in the Electron app when the selected file's extension is not .yaml, .yml, or .json. The check is purely extension-based (path.extname, lowercased) and runs before any content parsing. It guards the OpenAPI-spec import flow at the API boundary so only recognized spec file types proceed.","triggerScenarios":"User picks a file with an unsupported extension (.txt, .xml, .wsdl, no extension, .postman_collection) in the OpenAPI spec dialog; programmatic call to openApiSpec with a path whose extension is outside the allow-list.","commonSituations":"A spec saved with a .txt extension; a Postman/WSDL file selected by mistake; case sensitivity on case-sensitive filesystems (handled by toLowerCase, but the ext itself must be in the list); a file with no extension.","solutions":["Rename or re-save the spec with a .yaml, .yml, or .json extension.","If the content is valid YAML/JSON, copy it into a correctly named file.","When calling openApiSpec programmatically, ensure the path ends with a supported extension before invoking."],"exampleFix":"// before\nopenApiSpec(win, watcher, '/tmp/spec.txt');\n\n// after\nconst supported = ['.yaml', '.yml', '.json'];\nif (!supported.includes(path.extname('/tmp/spec.txt').toLowerCase())) {\n  throw new Error('Rename the file to .yaml/.yml/.json before importing');\n}","handlingStrategy":"validation","validationCode":"const VALID = ['.yaml', '.yml', '.json'];\nconst ext = path.extname(filePath).toLowerCase();\nif (!VALID.includes(ext)) {\n  throw new Error('Rename the file to .yaml, .yml, or .json before importing.');\n}","typeGuard":"const hasValidApiSpecExtension = (p) => ['.yaml', '.yml', '.json'].includes(path.extname(p).toLowerCase());","tryCatchPattern":null,"preventionTips":["Save OpenAPI specs with a .yaml/.yml/.json extension.","Configure the dialog filters (already set) so users cannot pick other types.","When scripting imports, assert the extension before calling openApiSpec."],"tags":["openapi","file-format","electron","validation","api-specs"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}