Skip to content
This repository was archived by the owner on Mar 5, 2026. It is now read-only.
This repository was archived by the owner on Mar 5, 2026. It is now read-only.

NodeError: Cannot call write after a stream was destroyed #561

@rhodgkins

Description

@rhodgkins

There seems to be an issue with .end being called when StreamConnection#close is called on an already closed stream.

It only seems to happen when the stream closes after it's been ABORTED (because the underlying system has closed the stream because it's been inactive for more than 600s), and then to clean up .close is called (on the JSONWriter for example).

Error when the stream is closed for inactivity:

stream_connection: connection closed | Error: 10 ABORTED: Closing the stream because it has been inactive for 600 seconds. Entity: projects/bookcreator-dev/datasets/custom_analytics/tables/events/streams/_default
    at callErrorFromStatus (/app/node_modules/@grpc/grpc-js/build/src/call.js:32:19)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client.js:421:73)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:324:181)
    at /app/node_modules/@grpc/grpc-js/build/src/resolving-call.js:135:78
    at processTicksAndRejections (internal/process/task_queues.js:77:11)
for call at
    at ServiceClientImpl.makeBidiStreamRequest (/app/node_modules/@grpc/grpc-js/build/src/client.js:405:32)
    at ServiceClientImpl.<anonymous> (/app/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
    at /app/node_modules/@google-cloud/bigquery-storage/build/src/v1/big_query_write_client.js:220:29
    at /app/node_modules/google-gax/build/src/streamingCalls/streamingApiCaller.js:46:28
    at /app/node_modules/google-gax/build/src/normalCalls/timeout.js:44:16
    at StreamProxy.setStream (/app/node_modules/google-gax/build/src/streamingCalls/streaming.js:248:24)
    at StreamingApiCaller.call (/app/node_modules/google-gax/build/src/streamingCalls/streamingApiCaller.js:54:16)
    at /app/node_modules/google-gax/build/src/createApiCall.js:112:30
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  code: 10,
  details: 'Closing the stream because it has been inactive for 600 seconds. Entity: projects/bookcreator-dev/datasets/custom_analytics/tables/events/streams/_default',
  metadata: Metadata {
    internalRepr: Map(1) { 'content-disposition' => [Array] },
    options: {}
  }
}

Then when calling .close:

stream_connection: on error | NodeError: Cannot call write after a stream was destroyed
    at doWrite (/app/node_modules/readable-stream/lib/_stream_writable.js:409:38)
    at writeOrBuffer (/app/node_modules/readable-stream/lib/_stream_writable.js:398:5)
    at StreamProxy.Writable.write (/app/node_modules/readable-stream/lib/_stream_writable.js:307:11)
    at StreamProxy.Duplexify.end (/app/node_modules/duplexify/index.js:234:41)
    at StreamConnection.close (/app/node_modules/@google-cloud/bigquery-storage/build/src/managedwriter/stream_connection.js:298:26)
    at Writer.close (/app/node_modules/@google-cloud/bigquery-storage/build/src/managedwriter/writer.js:113:32)
    at JSONWriter.close (/app/node_modules/@google-cloud/bigquery-storage/build/src/managedwriter/json_writer.js:97:22)
    at shutdown (/app/src/routes/events-insert.js:78:26)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async process.<anonymous> (/app/src/index.js:85:4)

To reproduce, open a connection to the default write stream and send some data using a JSONWriter. Then wait till the ABORTED error occurs and then call .close on the writer.

In StreamConnection#close, does #isConnectionClosed just need to be checked, instead of !this._connection?

Metadata

Metadata

Assignees

Labels

api: bigquerystorageIssues related to the googleapis/nodejs-bigquery-storage API.priority: p2Moderately-important priority. 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