winstonjs/winston · error · Error

ExceptionStream requires a TransportStream instance.

Error message

ExceptionStream requires a TransportStream instance.

What it means

ExceptionStream is an objectMode Readable wrapper that filters exception entries to a given transport. Its constructor validates that a TransportStream instance was provided; without one the stream would have nothing to write exceptions to, so it throws immediately.

Source

Thrown at lib/winston/exception-stream.js:28

const { Writable } = require('readable-stream');

/**
 * TODO: add class description.
 * @type {ExceptionStream}
 * @extends {Writable}
 */
module.exports = class ExceptionStream extends Writable {
  /**
   * Constructor function for the ExceptionStream responsible for wrapping a
   * TransportStream; only allowing writes of `info` objects with
   * `info.exception` set to true.
   * @param {!TransportStream} transport - Stream to filter to exceptions
   */
  constructor(transport) {
    super({ objectMode: true });

    if (!transport) {
      throw new Error('ExceptionStream requires a TransportStream instance.');
    }

    // Remark (indexzero): we set `handleExceptions` here because it's the
    // predicate checked in ExceptionHandler.prototype.__getExceptionHandlers
    this.handleExceptions = true;
    this.transport = transport;
  }

  /**
   * Writes the info object to our transport instance if (and only if) the
   * `exception` property is set on the info.
   * @param {mixed} info - TODO: add param description.
   * @param {mixed} enc - TODO: add param description.
   * @param {mixed} callback - TODO: add param description.
   * @returns {mixed} - TODO: add return description.
   * @private
   */
  _write(info, enc, callback) {

View on GitHub (pinned to ff0b79de85)

Solutions

  1. Pass a real transport instance: `new winston.ExceptionStream(new winston.transports.File({ filename: 'exceptions.log' }))`.
  2. Create/configure the transport before constructing the stream.
  3. Prefer `logger.exceptions.handle(transport)` so winston builds the ExceptionStream for you.
  4. Verify the argument is a transport (has `log` method / `_writableState`) before constructing.

Example fix

// before
const stream = new winston.ExceptionStream();

// after
const stream = new winston.ExceptionStream(
  new winston.transports.File({ filename: 'exceptions.log' })
);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!transport || typeof transport.log !== 'function') {
  throw new TypeError('ExceptionStream needs a TransportStream; got: ' + String(transport));
}

Type guard

function isTransportStream(x) { return !!x && typeof x.log === 'function' && !!x._writableState && x._writableState.objectMode; }

Try / catch

let stream;
try {
  stream = new winston.ExceptionStream(transport);
} catch (err) {
  if (err.message.startsWith('ExceptionStream requires')) {
    stream = new winston.ExceptionStream(new winston.transports.File({ filename: 'exceptions.log' }));
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling `new winston.ExceptionStream()` with no argument or a falsy value; passing something that is not a TransportStream (e.g. a plain object, a winston Logger, or a raw Node stream) in custom exception routing code.

Common situations: Custom uncaughtException plumbing where the transport variable failed to initialize; passing a logger instead of a transport; wiring transports after the stream was created.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of winstonjs/winston@ff0b79de85 (2026-08-31). Data as JSON: /api/errors/3de2f058cfc426dc. Report an issue: GitHub.