`AbortError: BodyStreamBuffer was aborted` when unsubscribing multipart subscription (BaseHttpLink)

Author: ItaiYosephiCreated Feb 24, 2026Updated May 10, 2026
Labels🏓 awaiting-team-response

Issue Description

Description

Calling subscription.unsubscribe() during a multipart HTTP subscription causes Uncaught (in promise) AbortError: BodyStreamBuffer was aborted. Related to #13125.

Root cause: The Observable teardown in BaseHttpLink calls controller.abort() when the subscription is unsubscribed. At that moment readMultipartBody is still consuming response.body via reader.read(). The abort kills the stream → reader.read() rejects with AbortError → .catch() propagates it → uncaught.

typescript
return () => {
  if (controller) controller.abort();  // ← triggers AbortError in readMultipartBody
};

Proposed fix: In src/link/http/BaseHttpLink.ts – track intentional teardown with a flag:

typescript
let didAbort = false;
return new Observable((observer) => {
  // ... fetch setup ...
  currentFetch(...)
    .then(...)
    .catch((err) => {
      cleanupController();
      if (didAbort) return;  // Intentional abort from teardown
      observer.error(err);
    });
  return () => {
    didAbort = true;
    if (controller) controller.abort();
  };
});

Reproduction

Consumer code – subscription with next handler that unsubscribes on error:

typescript
const subscription = client.subscribe({
  query: SomeDocument,
  variables: { input: { ... } },
}).subscribe({
  next: ({ data, error }) => {
    if (error) {
      subscription.unsubscribe();  // ← triggers AbortError
      setLoading(false);
      // handle error...
    } else {
      setData(data);
    }
  },
  complete: () => { ... },
});

Steps: Run multipart subscription (MSW mock or real server) → receive chunk with GraphQL error → subscription.unsubscribe() in next → AbortError in console.

Workaround: Don't call subscription.unsubscribe() in the error branch; let the stream complete naturally.

Environment

  • @apollo/client: 4.1.4
  • Multipart HTTP subscriptions (GraphOS)
  • Chrome

Link to Reproduction

https://codesandbox.io/p/github/ItaiYosephi/apollo-abort-error-repro/main?import=true

Reproduction Steps

  1. Open the reproduction

  2. Open the app in the browser (e.g. http://localhost:3000 or the CodeSandbox preview).

  3. Click "Start subscription" to start the multipart HTTP subscription.

  4. Check the browser console – you should see:

    Uncaught (in promise) AbortError: BodyStreamBuffer was aborted

What happens: The MSW mock returns a multipart response with an error chunk. When the next handler receives the error, it calls subscription.unsubscribe(). That triggers the teardown in BaseHttpLink, which calls controller.abort() while readMultipartBody is still consuming the stream, causing the uncaught AbortError.

@apollo/client version

4.1.4

Source: apollographql/apollo-client