paperclipai/paperclip · error · Error

Unsupported storage response body.

Error message

Unsupported storage response body.

What it means

Thrown by s3BodyToBuffer when the storage response body is a non-empty object but exposes none of the supported consumption interfaces: it is not a Buffer, not a Node Readable stream, and has neither transformToWebStream nor arrayBuffer methods. The helper cannot materialize bytes from it.

Source

Thrown at cli/src/commands/worktree.ts:347

    transformToWebStream?: () => ReadableStream<Uint8Array>;
    arrayBuffer?: () => Promise<ArrayBuffer>;
  };
  if (typeof candidate.transformToWebStream === "function") {
    const webStream = candidate.transformToWebStream();
    const reader = webStream.getReader();
    const chunks: Uint8Array[] = [];
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      if (value) chunks.push(value);
    }
    return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)));
  }
  if (typeof candidate.arrayBuffer === "function") {
    return Buffer.from(await candidate.arrayBuffer());
  }

  throw new Error("Unsupported storage response body.");
}

function normalizeS3Prefix(prefix: string | undefined): string {
  if (!prefix) return "";
  return prefix.trim().replace(/^\/+/, "").replace(/\/+$/, "");
}

function buildS3ObjectKey(prefix: string, objectKey: string): string {
  return prefix ? `${prefix}/${objectKey}` : objectKey;
}

const dynamicImport = new Function("specifier", "return import(specifier);") as (specifier: string) => Promise<any>;

function createConfiguredStorageFromPaperclipConfig(config: PaperclipConfig): ConfiguredStorage {
  if (config.storage.provider === "local_disk") {
    const baseDir = expandHomePrefix(config.storage.localDisk.baseDir);
    return {
      async getObject(companyId: string, objectKey: string) {

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Pin or upgrade @aws-sdk/client-s3 to a version whose Body is a Node Readable or has transformToWebStream/arrayBuffer.
  2. In tests, return a Readable.from(Buffer) or an object exposing arrayBuffer()/transformToWebStream() rather than a plain object.
  3. If using a custom S3-compatible client adapter, normalize its Body to one of the supported shapes before returning.
  4. Check for duplicate/incompatible @aws-sdk versions in node_modules (pnpm why @aws-sdk/client-s3).

Example fix

// before (test mock)
getObject: async () => ({ Body: { data: 'hi' } })
// after
getObject: async () => ({ Body: Readable.from(Buffer.from('hi')) })
Defensive patterns

Strategy: type-guard

Validate before calling

function isConsumableBody(body: unknown): boolean {
  return !!body && (
    Buffer.isBuffer(body) ||
    body instanceof Readable ||
    typeof (body as any)?.transformToWebStream === 'function' ||
    typeof (body as any)?.arrayBuffer === 'function'
  );
}

Type guard

function isSupportedBody(body: unknown): body is Buffer | Readable | { transformToWebStream(): ReadableStream<Uint8Array> } | { arrayBuffer(): Promise<ArrayBuffer> } {
  return isConsumableBody(body);
}

Try / catch

try {
  return await s3BodyToBuffer(resp.Body);
} catch (e) {
  if (e instanceof Error && e.message === 'Unsupported storage response body.') {
    throw new Error('S3 SDK version mismatch: update @aws-sdk/client-s3');
  }
  throw e;
}

Prevention

When it happens

Trigger: Using an @aws-sdk/client-s3 version whose response Body type differs (e.g. a newer SDK returning a different streaming primitive); mocking S3 responses with a plain object or string body; an S3-compatible vendor SDK that wraps responses in an unsupported shape; runtime where Readable cross-realm instanceof checks fail.

Common situations: Major @aws-sdk/client-s3 version upgrade changing the Body payload contract; polyfilled streams where instanceof Readable is unreliable across module realms; returning a string or TypedArray directly from a test double.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/771b27994f73428e. Report an issue: GitHub.