{"record":{"id":"c837cbd76b11878c","repo":"FuelLabs/fuels-ts","slug":"stream-parsing-error","errorCode":"STREAM_PARSING_ERROR","errorMessage":"Error while parsing stream data response: ${text}","messagePattern":"Error while parsing stream data response: (.+?)","errorType":"exception","errorClass":"FuelError","httpStatus":null,"severity":"error","filePath":"packages/account/src/providers/fuel-graphql-subscriber.ts","lineNumber":94,"sourceCode":"\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      /**\n       * Given the steam has a `data:.*\\n\\n` text stream, we will extract the data from the stream\n       * and parse it as a GraphQL response.\n       */\n      const matches = [...text.matchAll(regex)].flatMap((match) => match);\n      if (matches.length > 0) {\n        try {\n          const event = JSON.parse(matches[0].replace(/^data:/, ''));\n\n          return {\n            event,\n            done: false,\n            parsingLeftover: text.replace(matches[0], ''),\n          };\n        } catch (e) {\n          throw new FuelError(\n            ErrorCode.STREAM_PARSING_ERROR,\n            `Error while parsing stream data response: ${text}`\n          );\n        }\n      }\n\n      /**\n       * Otherwise, it's in another format, that we will read differently.\n       * This could be responses such as `keep-alive` messages.\n       */\n      const { value, done } = await reader.read();\n\n      if (done) {\n        return { event: undefined, done, parsingLeftover: '' };\n      }\n\n      /**\n       * We don't care about keep-alive messages.","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/FuelLabs/fuels-ts/blob/b3f37c91aca4aa9d5e4c0d3967f66237190826ea/packages/account/src/providers/fuel-graphql-subscriber.ts#L76-L112","documentation":"Thrown by FuelGraphqlSubscriber.readEvent when a chunk matched by the SSE 'data:.*\\n\\n' regex fails JSON.parse. The stream returned a payload shaped like an SSE data event but its body was not valid JSON, so the subscriber cannot decode it into a GraphQL response. This usually reflects a node/transport issue rather than a caller bug.","triggerScenarios":"Subscribing to a streaming operation (e.g. chain info, transaction status) against a node that returned a malformed/partial JSON event; an intermediary proxy truncated or rewrote the SSE frame; a keep-alive or error frame slipped past the keep-alive filter and matched the data regex; client/node version skew where the event shape changed.","commonSituations":"Node version mismatch (subscriber expects a specific SSE framing); a load balancer/proxy buffering or rewriting chunks; network interruption leaving a half-frame that matched the regex but is incomplete; debugging middleware injected non-JSON into the stream.","solutions":["Upgrade or align the fuel-core node version to one supported by this SDK version.","Connect directly to the node (bypass proxies/LBs that rewrite SSE) to rule out transport mangling.","Retry the subscription; transient partial frames can resolve on reconnect.","Capture the raw 'text' from the error message to identify what the node actually sent, then report/file an issue with that payload."],"exampleFix":"// before — direct call fails on a malformed frame\nconst sub = await provider.operations.status({ ... });\n\n// after — guard with retry on STREAM_PARSING_ERROR\nimport { FuelError, ErrorCode } from '@fuel-ts/errors';\nasync function safeSubscribe(fn, retries = 3) {\n  for (let i = 0; i < retries; i++) {\n    try { return await fn(); }\n    catch (e) {\n      if (e instanceof FuelError && e.code === ErrorCode.STREAM_PARSING_ERROR && i < retries - 1) continue;\n      throw e;\n    }\n  }\n}\nconst sub = await safeSubscribe(() => provider.operations.status({ ... }));","handlingStrategy":"retry","validationCode":"// No deterministic pre-check; the malformed frame arrives from the node.\n// Use a retry wrapper (see tryCatchPattern) for transient parse failures.\nnull","typeGuard":"function isStreamParseError(e: unknown): boolean {\n  return e instanceof FuelError && e.code === ErrorCode.STREAM_PARSING_ERROR;\n}","tryCatchPattern":"import { FuelError, ErrorCode } from '@fuel-ts/errors';\nasync function withStreamRetry<T>(fn: () => Promise<T>, retries = 3): Promise<T> {\n  for (let i = 0; i < retries; i++) {\n    try { return await fn(); }\n    catch (e) {\n      if (e instanceof FuelError && e.code === ErrorCode.STREAM_PARSING_ERROR && i < retries - 1) continue;\n      throw e;\n    }\n  }\n  throw new Error('unreachable');\n}","preventionTips":["Keep the fuel-core node version within the SDK's supported range.","Avoid proxies that buffer/rewrite SSE chunks between client and node.","Log the raw payload from the error to diagnose framing issues."],"tags":["network","streaming","graphql","sse","node-compat"],"backgroundTag":null,"analyzedSha":"b3f37c91aca4aa9d5e4c0d3967f66237190826ea","analyzedAt":"2026-08-12T20:30:56.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}