Skip to content

File.save fails with Node 18.13.0 #2133

@buu700

Description

@buu700

Environment details

  • OS: Debian 11.6 aarch64
  • Node.js version: 18.13.0
  • npm version: 9.3.1
  • @google-cloud/storage version: 6.9.0

Steps to reproduce

With a basic happy path usage of the library:

import {Storage} from '@google-cloud/storage';
const storage = new Storage(...).bucket(...);
await storage.file(...).save(...);

After upgrading from Node 18.12.1, I'm now getting the following error:

TypeError: RequestInit: duplex option is required when sending a body.
    at Object.fetch (node:internal/deps/undici/undici:14062:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  config: {
    method: 'PUT',
    url: 'https://storage.googleapis.com/upload/storage/v1/b/[redacted]',
    headers: {
      'x-goog-api-client': 'gl-node/18.13.0 gccl/6.9.0 gccl-invocation-id/[redacted]',
      'Content-Range': 'bytes 0-*/*',
      Authorization: 'Bearer [redacted]',
      Accept: 'application/json'
    },
    body: <ref *1> Readable {
      _readableState: ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: [],
        flowing: false,
        ended: false,
        endEmitted: false,
        reading: true,
        constructed: true,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: true,
        resumeScheduled: false,
        errorEmitted: false,
        emitClose: true,
        autoDestroy: true,
        destroyed: false,
        errored: null,
        closed: false,
        closeEmitted: false,
        defaultEncoding: 'utf8',
        awaitDrainWriters: null,
        multiAwaitDrain: false,
        readingMore: false,
        dataEmitted: true,
        decoder: null,
        encoding: null,
        [Symbol(kPaused)]: null
      },
      _read: [AsyncFunction: read],
      _events: [Object: null prototype] {
        readable: [Function (anonymous)],
        end: [Function (anonymous)],
        finish: [Function (anonymous)],
        error: [Function (anonymous)],
        close: [Function (anonymous)]
      },
      _eventsCount: 5,
      _maxListeners: undefined,
      __zone_symbol__readablefalse: [
        ZoneTask {
          _zone: Zone {
            _parent: null,
            _name: '<root>',
            _properties: {},
            _zoneDelegate: [_ZoneDelegate]
          },
          runCount: 2,
          _zoneDelegates: [],
          _state: 'scheduled',
          type: 'eventTask',
          source: 'Readable.addListener:readable',
          data: undefined,
          scheduleFn: [Function: customScheduleNonGlobal],
          cancelFn: [Function: customCancelNonGlobal],
          callback: [Function: next],
          invoke: [Function (anonymous)],
          options: undefined,
          target: [Circular *1],
          capture: false,
          eventName: 'readable'
        }
      ],
      __zone_symbol__endfalse: [
        ZoneTask {
          _zone: Zone {
            _parent: null,
            _name: '<root>',
            _properties: {},
            _zoneDelegate: [_ZoneDelegate]
          },
          runCount: 0,
          _zoneDelegates: [],
          _state: 'scheduled',
          type: 'eventTask',
          source: 'Readable.addListener:end',
          data: undefined,
          scheduleFn: [Function: customScheduleNonGlobal],
          cancelFn: [Function: customCancelNonGlobal],
          callback: [Function: onend],
          invoke: [Function (anonymous)],
          options: undefined,
          target: [Circular *1],
          capture: false,
          eventName: 'end'
        }
      ],
      __zone_symbol__finishfalse: [
        ZoneTask {
          _zone: Zone {
            _parent: null,
            _name: '<root>',
            _properties: {},
            _zoneDelegate: [_ZoneDelegate]
          },
          runCount: 0,
          _zoneDelegates: [],
          _state: 'scheduled',
          type: 'eventTask',
          source: 'Readable.addListener:finish',
          data: undefined,
          scheduleFn: [Function: customScheduleNonGlobal],
          cancelFn: [Function: customCancelNonGlobal],
          callback: [Function: onfinish],
          invoke: [Function (anonymous)],
          options: undefined,
          target: [Circular *1],
          capture: false,
          eventName: 'finish'
        }
      ],
      __zone_symbol__errorfalse: [
        ZoneTask {
          _zone: Zone {
            _parent: null,
            _name: '<root>',
            _properties: {},
            _zoneDelegate: [_ZoneDelegate]
          },
          runCount: 0,
          _zoneDelegates: [],
          _state: 'scheduled',
          type: 'eventTask',
          source: 'Readable.addListener:error',
          data: undefined,
          scheduleFn: [Function: customScheduleNonGlobal],
          cancelFn: [Function: customCancelNonGlobal],
          callback: [Function: onerror],
          invoke: [Function (anonymous)],
          options: undefined,
          target: [Circular *1],
          capture: false,
          eventName: 'error'
        }
      ],
      __zone_symbol__closefalse: [
        ZoneTask {
          _zone: Zone {
            _parent: null,
            _name: '<root>',
            _properties: {},
            _zoneDelegate: [_ZoneDelegate]
          },
          runCount: 0,
          _zoneDelegates: [],
          _state: 'scheduled',
          type: 'eventTask',
          source: 'Readable.addListener:close',
          data: undefined,
          scheduleFn: [Function: customScheduleNonGlobal],
          cancelFn: [Function: customCancelNonGlobal],
          callback: [Function: onclose],
          invoke: [Function (anonymous)],
          options: undefined,
          target: [Circular *1],
          capture: false,
          eventName: 'close'
        }
      ],
      [Symbol(kCapture)]: false
    },
    signal: AbortSignal {},
    validateStatus: [Function (anonymous)],
    paramsSerializer: [Function: paramsSerializer],
    responseType: 'json'
  }
}

Related issue: nodejs/node#46323

Edit: Replaced the internal Node stack trace with a more relevant error message (context here).

Metadata

Metadata

Assignees

Labels

api: storageIssues related to the googleapis/nodejs-storage API.externalThis issue is blocked on a bug with the actual product.needs more infoThis issue needs more information from the customer to proceed.priority: p3Desirable enhancement or fix. May not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions