FuelLabs/fuels-ts · error · FuelError

STREAM_PARSING_ERROR

STREAM_PARSING_ERROR

Error message

Error while parsing stream data response: ${text}

What it means

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.

Source

Thrown at packages/account/src/providers/fuel-graphql-subscriber.ts:94

    // eslint-disable-next-line no-constant-condition
    while (true) {
      /**
       * Given the steam has a `data:.*\n\n` text stream, we will extract the data from the stream
       * and parse it as a GraphQL response.
       */
      const matches = [...text.matchAll(regex)].flatMap((match) => match);
      if (matches.length > 0) {
        try {
          const event = JSON.parse(matches[0].replace(/^data:/, ''));

          return {
            event,
            done: false,
            parsingLeftover: text.replace(matches[0], ''),
          };
        } catch (e) {
          throw new FuelError(
            ErrorCode.STREAM_PARSING_ERROR,
            `Error while parsing stream data response: ${text}`
          );
        }
      }

      /**
       * Otherwise, it's in another format, that we will read differently.
       * This could be responses such as `keep-alive` messages.
       */
      const { value, done } = await reader.read();

      if (done) {
        return { event: undefined, done, parsingLeftover: '' };
      }

      /**
       * We don't care about keep-alive messages.

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Upgrade or align the fuel-core node version to one supported by this SDK version.
  2. Connect directly to the node (bypass proxies/LBs that rewrite SSE) to rule out transport mangling.
  3. Retry the subscription; transient partial frames can resolve on reconnect.
  4. Capture the raw 'text' from the error message to identify what the node actually sent, then report/file an issue with that payload.

Example fix

// before — direct call fails on a malformed frame
const sub = await provider.operations.status({ ... });

// after — guard with retry on STREAM_PARSING_ERROR
import { FuelError, ErrorCode } from '@fuel-ts/errors';
async function safeSubscribe(fn, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try { return await fn(); }
    catch (e) {
      if (e instanceof FuelError && e.code === ErrorCode.STREAM_PARSING_ERROR && i < retries - 1) continue;
      throw e;
    }
  }
}
const sub = await safeSubscribe(() => provider.operations.status({ ... }));
Defensive patterns

Strategy: retry

Validate before calling

// No deterministic pre-check; the malformed frame arrives from the node.
// Use a retry wrapper (see tryCatchPattern) for transient parse failures.
null

Type guard

function isStreamParseError(e: unknown): boolean {
  return e instanceof FuelError && e.code === ErrorCode.STREAM_PARSING_ERROR;
}

Try / catch

import { FuelError, ErrorCode } from '@fuel-ts/errors';
async function withStreamRetry<T>(fn: () => Promise<T>, retries = 3): Promise<T> {
  for (let i = 0; i < retries; i++) {
    try { return await fn(); }
    catch (e) {
      if (e instanceof FuelError && e.code === ErrorCode.STREAM_PARSING_ERROR && i < retries - 1) continue;
      throw e;
    }
  }
  throw new Error('unreachable');
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/c837cbd76b11878c. Report an issue: GitHub.