How to fix TypeError: stream._write is not a function in Node.js
This error occurs when implementing a custom writable stream without properly defining the required _write() method. Node.js expects all custom writable streams to implement this internal method to handle data processing.
Quick fix
Fixes TypeError
const { Writable } = require('stream');
class MyWritable extends Writable {
_write(chunk, encoding, callback) {
// Process the chunk here
console.log('Writing:', chunk.toString());
// Call callback when done (or with error if failed)
callback();
}
}
const myStream = new MyWritable();
myStream.write('test data'); // Now works correctly- Verify your custom stream class implements _write()
- Use the write option in the constructor if not extending the class
- Ensure the callback is always called
- Check for proper method binding
const { Writable } = require('stream');class MyWritable extends Writable {_write(chunk, encoding, callback) {// Process the chunk hereconsole.log('Writing:', chunk.toString());// Call callback when done (or with error if failed)callback();}}const myStream = new MyWritable();myStream.write('test data'); // Now works correctlyTypeError: stream._write is not a function
What this error means
This TypeError indicates that a custom writable stream class has been created but lacks a proper implementation of the `_write()` method. In Node.js streams, there's an important distinction: `.write()` is the public API that consumers use to write data to a stream, while `._write()` is an internal method that stream implementers must provide to define how data should actually be processed and stored. When you extend the `Writable` class to create a custom stream, Node.js requires you to implement the `_write()` method (or `_writev()` for handling multiple chunks). This method is called internally by the stream whenever data needs to be written to the underlying destination. Without this implementation, the stream has no way to process the data, resulting in this error. The error typically surfaces when the stream tries to process data for the first time, as Node.js attempts to call the missing `_write()` method.
Typical symptoms
- TypeError thrown when writing data to a custom stream
- Error message specifically mentions "stream._write is not a function"
- Error occurs immediately when attempting to write to the stream
- Custom writable stream fails during initialization or first write operation
- Stack trace points to stream implementation code
Common causes
- Extended Writable class without implementing the required _write() method
- Forgot to define _write() when creating a custom writable stream
- Incorrectly passed a non-function value as the _write implementation
- Used arrow function that doesn't properly bind to the stream instance
- Constructor options missing the write function when not using class extension
How to fix "TypeError: stream._write is not a function"
Check that your custom writable stream class properly implements the _write() method with the correct signature:
const { Writable } = require('stream');
class MyWritable extends Writable {
_write(chunk, encoding, callback) {
// Process the chunk here
console.log('Writing:', chunk.toString());
// Call callback when done (or with error if failed)
callback();
}
}
const myStream = new MyWritable();
myStream.write('test data'); // Now works correctlyThe _write() method must accept three parameters:
- chunk: The data to write (Buffer or string)
- encoding: The encoding type if chunk is a string
- callback: Function to call when processing is complete
If you're not creating a subclass, pass the write function in the options object:
const { Writable } = require('stream');
const myStream = new Writable({
write(chunk, encoding, callback) {
// Process the chunk
console.log('Writing:', chunk.toString());
callback();
}
});
myStream.write('test data'); // Works correctlyThe constructor will automatically convert the write option to the internal _write() method.
The _write() method must always invoke the callback to signal completion:
class MyWritable extends Writable {
_write(chunk, encoding, callback) {
try {
// Your processing logic
this.processData(chunk);
// Signal success
callback();
} catch (error) {
// Signal error
callback(error);
}
}
}Failing to call the callback will cause the stream to hang. Call callback() on success or callback(error) on failure.
Ensure _write() is defined as a method, not as an arrow function property:
// CORRECT: Method definition
class MyWritable extends Writable {
_write(chunk, encoding, callback) {
// Has proper 'this' binding
this.someProperty = chunk;
callback();
}
}
// INCORRECT: Arrow function as property
class MyWritable extends Writable {
_write = (chunk, encoding, callback) => {
// May cause issues with stream internals
callback();
}
}Use standard method syntax for stream interface methods to ensure proper binding.
For better performance with multiple writes, implement _writev():
class MyWritable extends Writable {
_write(chunk, encoding, callback) {
// Handle single chunk
this.processSingle(chunk);
callback();
}
_writev(chunks, callback) {
// Handle multiple chunks at once
const data = chunks.map(c => c.chunk);
this.processBatch(data);
callback();
}
}Implementing _writev() is optional but can improve performance when multiple writes are queued.
Advanced notes
Understanding Stream Internals: The distinction between write() and _write() reflects the separation of public API and implementation details. The write() method handles buffering, backpressure, and queuing, while _write() focuses solely on processing individual chunks. Node.js manages the complexity of stream control flow, and you only need to implement the data processing logic.
Duplex and Transform Streams: If you're implementing a duplex or transform stream, you'll need to implement both _read() and _write() (or _transform() for transform streams). Each has specific requirements and callback semantics.
Async/Await Pattern: While _write() uses callbacks, you can use async/await internally as long as you call the callback:
class AsyncWritable extends Writable {
async _write(chunk, encoding, callback) {
try {
await this.asyncOperation(chunk);
callback();
} catch (error) {
callback(error);
}
}
}Error Handling: Always handle errors gracefully in _write(). Pass errors to the callback rather than throwing, as thrown errors may not be properly caught by the stream's error handling mechanism. The stream will emit an 'error' event when you call callback(error).
Performance Considerations: Keep _write() operations efficient. If processing is CPU-intensive, consider using worker threads or breaking operations into smaller chunks to avoid blocking the event loop. The callback-based design allows for non-blocking I/O operations.
Frequently asked questions
- What does "TypeError" mean?
- This TypeError indicates that a custom writable stream class has been created but lacks a proper implementation of the _write() method. _write() is an internal method that stream implementers must provide to define how data should actually be processed and stored. js requires you to implement the _write() method (or _writev() for handling multiple chunks).
- How do I fix "TypeError"?
- This error occurs when implementing a custom writable stream without properly defining the required _write() method. Node.js expects all custom writable streams to implement this internal method to handle data processing.
- What causes "TypeError"?
- Extended Writable class without implementing the required _write() method Forgot to define _write() when creating a custom writable stream Incorrectly passed a non-function value as the _write implementation
- Is the "TypeError" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐Node.js Stream API - Writable streams(Official Docs)
- ๐
- ๐