This error occurs when a PassThrough stream is used before proper initialization or when extending the PassThrough class without calling the parent constructor correctly.
This error indicates that a PassThrough stream instance is being used in an invalid state, typically because the stream's internal initialization sequence was not completed properly. PassThrough streams are simple Transform streams that pass input bytes directly to output, but they still require proper initialization through their constructor. The most common cause is extending the PassThrough class and either forgetting to call super() in the child class constructor, or calling it incorrectly. This prevents the stream's internal buffers and state from being set up correctly, leading to failures when trying to read, write, or pipe data. Another scenario is attempting to use a PassThrough stream that was created but never properly instantiated with the "new" keyword, or using stream methods before the constructor has finished executing.
If you're extending the PassThrough class, ensure super() is called first:
const { PassThrough } = require('stream');
class MyPassThrough extends PassThrough {
constructor(options) {
// CORRECT: Call super() first, before accessing this
super(options);
this.customProperty = 'value';
}
}
// Incorrect example:
class BrokenPassThrough extends PassThrough {
constructor(options) {
this.customProperty = 'value'; // ERROR: accessing this before super()
super(options);
}
}The super() call must be the first statement in the constructor before any use of "this".
Always create PassThrough instances using the "new" keyword:
const { PassThrough } = require('stream');
// CORRECT:
const passThrough = new PassThrough();
// INCORRECT:
const broken = PassThrough(); // Missing "new" keywordWithout "new", the function is called directly and won't properly initialize the stream object.
If passing options to PassThrough, ensure they're valid stream options:
const { PassThrough } = require('stream');
// Valid options:
const stream = new PassThrough({
highWaterMark: 16384,
encoding: 'utf8',
objectMode: false,
autoDestroy: true
});
// Check for typos or invalid options:
const invalid = new PassThrough({
highWaterMarc: 16384, // Typo: should be highWaterMark
invalidOption: true // Not a valid stream option
});Invalid options may not throw immediately but can cause initialization issues.
Always attach error handlers to PassThrough streams to catch initialization and runtime errors:
const { PassThrough } = require('stream');
const passThrough = new PassThrough();
passThrough.on('error', (err) => {
console.error('PassThrough error:', err);
// Handle the error appropriately
});
// If using in a pipeline:
const { pipeline } = require('stream');
const fs = require('fs');
pipeline(
fs.createReadStream('input.txt'),
passThrough,
fs.createWriteStream('output.txt'),
(err) => {
if (err) {
console.error('Pipeline error:', err);
}
}
);Error handlers prevent uncaught exceptions from crashing your application.
### Extending PassThrough Correctly
When creating custom stream classes, the initialization order is critical:
const { PassThrough } = require('stream');
class CustomPassThrough extends PassThrough {
constructor(options = {}) {
// 1. Call super() first with options
super({
...options,
// You can add default options here
highWaterMark: options.highWaterMark || 64 * 1024
});
// 2. Then initialize your custom properties
this.bytesProcessed = 0;
this.startTime = Date.now();
// 3. Set up event listeners if needed
this.on('data', (chunk) => {
this.bytesProcessed += chunk.length;
});
}
getStats() {
return {
bytes: this.bytesProcessed,
duration: Date.now() - this.startTime
};
}
}
const stream = new CustomPassThrough();### Common Patterns vs Anti-Patterns
Good Pattern: Always use the new keyword and handle errors
const passThrough = new PassThrough()
.on('error', handleError)
.on('finish', handleFinish);Anti-Pattern: Storing uninitialized references
let stream;
// ... some code ...
stream.write('data'); // May fail if stream never initialized### Multiple Consumption Methods Warning
Never mix different consumption methods on the same PassThrough stream. Choose one approach:
- Option 1: Using pipe()
- Option 2: Using on('data') events
- Option 3: Using async iterators
Mixing these can cause initialization state issues and unpredictable behavior.
Error: Listener already called (once event already fired)
EventEmitter listener already called with once()
Error: EACCES: permission denied, open '/root/file.txt'
EACCES: permission denied
Error: Invalid encoding specified (stream encoding not supported)
How to fix Invalid encoding error in Node.js readable streams
Error: EINVAL: invalid argument, open
EINVAL: invalid argument, open
TypeError: readableLength must be a positive integer (stream config)
TypeError: readableLength must be a positive integer in Node.js streams