aws-sdk-js-v3 icon indicating copy to clipboard operation
aws-sdk-js-v3 copied to clipboard

"ReferenceError: ReadableStream is not defined" from "@aws-sdk/lib-storage" on a stream pipe

Open oprogramador opened this issue 1 year ago • 6 comments

Checkboxes for prior research

Describe the bug

I have several issues related to uploading files into S3. Normally, it works even with large files but in some cases, it fails. This issue is easy to reproduce and looks to be definitely a bug inside the AWS SDK. Even if I do something wrong, I should get an appropriate error message.

SDK version number

"@aws-sdk/client-s3": "^3.350.0", "@aws-sdk/lib-storage": "^3.499.0",

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v16.19.0

Reproduction Steps

Run the following script with Node.js (node 1.js).

const Stream = require('stream');
const bluebird = require('bluebird');
const { Upload } = require('@aws-sdk/lib-storage');
const { S3 } = require('@aws-sdk/client-s3');

const run = async () => {
  const readable = new Stream.Readable({
    read() { },
  });
  const writable = Stream.Writable({
    write() {},
  });

  const params = {
    Bucket: 'my-bucket',
    Key: 'my-dir/pipe0.txt',
    Body: writable,
  };

  const uploadToS3 = new Upload({
    client: new S3(),
    queueSize: 4,
    partSize: 1024 * 1024 * 5,
    leavePartsOnError: true,
    params,
  });
  readable.pipe(writable);

  const result = readable.push('foo');
  console.log({ result });

  await bluebird.delay(5000);
  writable.end();
  await uploadToS3.done();
};

run()
  .then(() => console.log('done'))
  .catch((error) => console.error(error));

Observed Behavior

⟩ node 1.js 
{ result: true }
ReferenceError: ReadableStream is not defined
    at getChunk (/home/me/node_modules/@aws-sdk/lib-storage/dist-cjs/index.js:149:30)
    at _Upload.__doMultipartUpload (/home/me/node_modules/@aws-sdk/lib-storage/dist-cjs/index.js:361:24)
    at _Upload.done (/home/me/node_modules/@aws-sdk/lib-storage/dist-cjs/index.js:190:37)
    at run (/home/me/1.js:34:20)

Expected Behavior

A file should be uploaded into the S3 bucket (without any error).

Possible Solution

No response

Additional Information/Context

This script works (with just a file stream instead of anything from AWS SDK).

const fs = require('fs');
const bluebird = require('bluebird');

const run = async () => {
  const readable = new Stream.Readable({
    read() { },
  });
  const writable = fs.createWriteStream('./file-foo.txt');

  readable.pipe(writable);

  const result = readable.push('foo');
  console.log({ result });

  await bluebird.delay(5000);
  writable.end();
};

run()
  .then(() => console.log('done'))
  .catch((error) => console.error(error));

oprogramador avatar Jan 28 '24 02:01 oprogramador

The following issues look to be related. However, I cannot find a pipe( example in any of them so IMO this issue should be kept open.

  • https://github.com/aws/aws-sdk-js-v3/issues/3923
  • https://github.com/aws/aws-sdk-js-v3/issues/2522
  • https://github.com/aws/aws-sdk-js-v3/issues/2312
  • https://github.com/aws/aws-sdk-js-v3/issues/3807
  • https://github.com/aws/aws-sdk-js-v3/issues/3063

oprogramador avatar Jan 28 '24 03:01 oprogramador

Hi @oprogramador , are you sure that the Body is intented to refer to a function of type Writable? Since the Body accepts these types string | Uint8Array | Buffer | Readable

major-winter avatar Jan 29 '24 07:01 major-winter

@major-winter

When passing the readable stream as a part of params instead of that writable stream, I get no error but no file appears on S3 either.

Anyway, if it doesn't accept a writable, a clear error message should be thrown.

oprogramador avatar Jan 30 '24 02:01 oprogramador

https://github.com/aws/aws-sdk-js-v3/issues/6013 related?

NorseGaud avatar Apr 20 '24 17:04 NorseGaud

Hi everyone on the thread - appreciate your patience.

You can resolve this by importing ReadableStream like so

import { ReadableStream } from 'web-streams-polyfill';

Let us know if issue persists and we'd be happy to investigate further.

aBurmeseDev avatar May 18 '24 00:05 aBurmeseDev

@aBurmeseDev

After adding const { ReadableStream } = require('web-streams-polyfill');, this issue keeps happening.

oprogramador avatar May 18 '24 00:05 oprogramador

Can you share your updated code as well as the logs? Add this middleware stack to your client to retrieve request logs.

client.middlewareStack.add(
  (next, context) => async (args) => {
    console.log("AWS SDK context", context.clientName, context.commandName);
    console.log("AWS SDK request input", args.input);
    const result = await next(args);
    console.log("AWS SDK request output:", result.output);
    return result;
  },
  {
    name: "MyMiddleware",
    step: "build",
    override: true,
  }
);

aBurmeseDev avatar May 19 '24 21:05 aBurmeseDev

You should be able to reproduce, using the details from this issue description.

This is resolved a long time ago on my side with a workaround.

oprogramador avatar May 19 '24 21:05 oprogramador

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

github-actions[bot] avatar Jun 03 '24 00:06 github-actions[bot]