winstonjs/winston · error · Error

Cannot set ${name} and ${target} together

Error message

Cannot set ${name} and ${target} together

What it means

The File transport constructor defines throwIf(target, ...names) which throws when mutually exclusive options are set together: the message lists which two options conflict. In winston v3 a File transport must log either to a stream or to a file (filename/maxsize) — never both — because the internal pipeline is built one way or the other.

Source

Thrown at lib/winston/transports/file.js:44

 */
module.exports = class File extends TransportStream {
  /**
   * Constructor function for the File transport object responsible for
   * persisting log messages and metadata to one or more files.
   * @param {Object} options - Options for this instance.
   */
  constructor(options = {}) {
    super(options);

    // Expose the name of this Transport on the prototype.
    this.name = options.name || 'file';

    // Helper function which throws an `Error` in the event that any of the
    // rest of the arguments is present in `options`.
    function throwIf(target, ...args) {
      args.slice(1).forEach(name => {
        if (options[name]) {
          throw new Error(`Cannot set ${name} and ${target} together`);
        }
      });
    }

    // Setup the base stream that always gets piped to to handle buffering.
    this._stream = new PassThrough();
    this._stream.setMaxListeners(30);

    // Bind this context for listener methods.
    this._onError = this._onError.bind(this);

    if (options.filename || options.dirname) {
      throwIf('filename or dirname', 'stream');
      this._basename = this.filename = options.filename
        ? path.basename(options.filename)
        : 'winston.log';

      this.dirname = options.dirname || path.dirname(options.filename);

View on GitHub (pinned to ff0b79de85)

Solutions

  1. Pick one target: remove the stream option and keep filename (most common), or remove filename/maxsize and keep stream.
  2. If config is merged, explicitly delete the conflicting key before constructing: delete opts.stream when filename is set.
  3. If you need both streamed writes and rotation, pipe your own stream into the transport's stream instead of passing both options.

Example fix

// before
new winston.transports.File({ filename: 'app.log', stream: fs.createWriteStream('app.log') });
// after
new winston.transports.File({ filename: 'app.log' });
Defensive patterns

Strategy: validation

Validate before calling

function makeFileTransport(opts) {
  if (opts.stream && (opts.filename || opts.maxsize)) {
    throw new TypeError('File transport: stream is mutually exclusive with filename/maxsize');
  }
  return new winston.transports.File(opts);
}

Try / catch

try {
  fileTransport = new winston.transports.File(mergedOpts);
} catch (err) {
  if (err.message.startsWith('Cannot set')) {
    const { stream, ...rest } = mergedOpts; // prefer filename
    fileTransport = new winston.transports.File(rest);
  } else throw err;
}

Prevention

When it happens

Trigger: new winston.transports.File({ stream: fs.createWriteStream('a.log'), filename: 'b.log' }) or { stream, maxsize } — the constructor calls throwIf('stream', 'filename', 'maxsize') and throwIf('filename', 'stream').

Common situations: Merging config objects where defaults include filename and the caller also injects a stream; copying an existing transport's options and adding a stream for rotation handling; migrating code that piped streams manually on top of filename-based logging.

Related errors


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