{"record":{"id":"ffa78e55bb4a4e37","repo":"usebruno/bruno","slug":"failed-to-parse-the-file-ensure-it-is-valid-json-ffa78e","errorCode":null,"errorMessage":"Failed to parse the file – ensure it is valid JSON or YAML","messagePattern":"Failed to parse the file – ensure it is valid JSON or YAML","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-app/src/utils/importers/file-reader.js","lineNumber":22,"sourceCode":"/**\n * Parse a File object as JSON or YAML and return the parsed object.\n * Throws with a user-friendly message on parse failure.\n */\nexport const parseFileAsJsonOrYaml = async (file) => {\n  try {\n    const text = await file.text();\n    let parsed;\n    if (file.name.toLowerCase().endsWith('.json')) {\n      parsed = JSON.parse(text);\n    } else {\n      parsed = jsyaml.load(text);\n    }\n    if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n      throw new Error('Document root must be an object');\n    }\n    return parsed;\n  } catch {\n    throw new Error('Failed to parse the file – ensure it is valid JSON or YAML');\n  }\n};\n\nconst readFile = (file) => {\n  return new Promise((resolve, reject) => {\n    const fileReader = new FileReader();\n    fileReader.onload = (e) => {\n      try {\n        const parsed = JSON.parse(e.target.result);\n        resolve({ fileName: file.name, content: parsed });\n      } catch (err) {\n        console.error(err);\n        reject(new BrunoError(`Unable to parse JSON file: ${file.name}`));\n      }\n    };\n    fileReader.onerror = (err) => reject(err);\n    fileReader.readAsText(file);\n  });","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-app/src/utils/importers/file-reader.js#L4-L40","documentation":"Catch-all thrown by the async parse path in file-reader.js. It replaces any JSON.parse/jsyaml.load failure, or the explicit 'Document root must be an object' check, with a single user-facing message asking for valid JSON or YAML.","triggerScenarios":"A file whose text is not parseable JSON (when .json) or YAML (otherwise), OR a file whose parsed root is not an object (array, primitive, null). The try block swallows the original error and substitutes this generic message.","commonSituations":"Corrupted export, BOM/encoding issues, accidental plain-text content, a YAML file with tabs, or a JSON file whose top level is an array.","solutions":["Open the file in an editor and run a JSON/YAML linter to find the syntax error.","If the root is an array, wrap it in an object or use an importer that accepts arrays.","Save the file as UTF-8 without BOM and retry."],"exampleFix":"// before: file contains '[1, 2, 3]' (array root)\n// after: file contains\n{\n  \"info\": { \"type\": \"bruno-environment\" },\n  \"environments\": []\n}","handlingStrategy":"validation","validationCode":"let parsed;\ntry {\n  parsed = file.name.toLowerCase().endsWith('.json') ? JSON.parse(text) : jsyaml.load(text);\n} catch (e) {\n  throw new Error(`Syntax error: ${e.message}`);\n}\nif (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n  throw new Error('Root must be a JSON/YAML object');\n}","typeGuard":"function isObjectRoot(parsed) {\n  return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed);\n}","tryCatchPattern":"try {\n  await parseFile(file);\n} catch (err) {\n  if (err.message.includes('valid JSON or YAML')) {\n    // lint the file with a JSON/YAML validator before retrying\n  }\n  throw err;\n}","preventionTips":["Lint files with a JSON/YAML validator before import.","Save files as UTF-8 without BOM.","Wrap array roots in an object or use an importer that accepts arrays."],"tags":["import","filesystem","json","yaml","parsing"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}