{"record":{"id":"c848c34fdc118500","repo":"usebruno/bruno","slug":"failed-to-parse-context-error-message-c848c3","errorCode":null,"errorMessage":"Failed to parse ${context}: ${error.message}","messagePattern":"Failed to parse (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-requests/src/ws/ws-client.js","lineNumber":21,"sourceCode":"import { getParsedWsUrlObject } from './ws-url';\n\n/**\n * Safely parse JSON string with error handling\n * @param {string} jsonString - The JSON string to parse\n * @param {string} context - Context for error messages\n * @returns {Object} Parsed object or throws error with context\n * @throws {Error} If JSON parsing fails\n */\nconst safeParseJSON = (jsonString, context = 'JSON string') => {\n  try {\n    return JSON.parse(jsonString);\n  } catch (error) {\n    const errorMessage = `Failed to parse ${context}: ${error.message}`;\n    console.error(errorMessage, {\n      originalString: jsonString,\n      parseError: error\n    });\n    throw new Error(errorMessage);\n  }\n};\n\nconst normalizeMessageByFormat = (message, format) => {\n  if (!message) {\n    return '';\n  }\n  switch (format) {\n    case 'json':\n      // If it was already stringified, do not double encode\n      if (typeof message === 'string') {\n        return message;\n      }\n      return JSON.stringify(message);\n    case 'raw':\n    case 'xml':\n      return message;\n    default: {","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-requests/src/ws/ws-client.js#L3-L39","documentation":"Thrown by safeParseJSON in the WebSocket client when JSON.parse fails on an inbound or user-supplied string. The wrapper prepends the calling context to the message and console.errors the original string plus the parse error before re-throwing, so debugging info is captured. Any caller that hands a non-JSON string to safeParseJSON triggers it.","triggerScenarios":"The server sends a plain-text, binary, XML, or HTML frame on a channel the client assumed was JSON; a partial/malformed frame is delivered; the user typed a non-JSON message into a 'json' format send box; BOM or control characters precede the JSON; the message is a valid JSON fragment that needs reassembly.","commonSituations":"WS endpoint that mixes text and JSON frames; reverse proxy returning an HTML error page over the WS upgrade; client/server version mismatch on the message schema; user pasting free text into a JSON-mode send field; locale-specific number formatting producing trailing commas.","solutions":["Confirm the server actually emits JSON for the frame being parsed; if it can emit other formats, branch on message type before calling safeParseJSON.","If the frame is text-not-JSON by design, treat it as raw (use the 'raw'/'xml' normalizeMessageByFormat branch) instead of forcing JSON.","Strip a leading BOM or whitespace before parsing: jsonString.replace(/^\\uFEFF\\s*/, '').","For partial frames, ensure the WS client is not splitting on a wrong delimiter; assemble complete messages first."],"exampleFix":"// before\nconst parsed = safeParseJSON(event.data, 'server message');\n\n// after\nconst raw = typeof event.data === 'string' ? event.data.replace(/^\\uFEFF\\s*/, '') : '';\nif (!raw.startsWith('{') && !raw.startsWith('[')) {\n  console.warn('non-JSON frame, treating as raw', raw);\n} else {\n  const parsed = safeParseJSON(raw, 'server message');\n}","handlingStrategy":"try-catch","validationCode":"function looksLikeJson(s) {\n  if (typeof s !== 'string') return false;\n  const t = s.replace(/^\\uFEFF\\s*/, '').trim();\n  return t.startsWith('{') || t.startsWith('[');\n}\n// only invoke safeParseJSON when the frame is plausibly JSON\nconst data = looksLikeJson(frame) ? safeParseJSON(frame, 'server message') : frame;","typeGuard":"function isJsonParseError(e) {\n  return e instanceof Error && /^Failed to parse .+:/.test(e.message);\n}","tryCatchPattern":"try {\n  return safeParseJSON(raw, 'ws.serverMessage');\n} catch (e) {\n  if (!isJsonParseError(e)) throw e;\n  console.warn('dropping non-JSON frame', { len: raw?.length, head: raw?.slice?.(0, 64) });\n  return null; // or route to a raw-text handler\n}","preventionTips":["Branch on message format/type before parsing; do not assume every frame on a WS is JSON.","Negotiate a subprotocol so text vs binary vs json is explicit at connect time.","Strip BOM/whitespace and validate the first non-whitespace char before JSON.parse.","Log the head of unparsable frames to catch server-side regressions early."],"tags":["websocket","json","parsing","protocol","runtime"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}