winstonjs/winston · error · Error

{ %s } was removed in winston@3.0.0. Use a custom winston.fo

Error message

{ %s } was removed in winston@3.0.0.
Use a custom winston.format = winston.format(function) instead.

What it means

This variant of the deprecation helper (`useFormat` in lib/winston/common.js) targets winston 2.x APIs that were replaced by the winston 3 format system. The error appends the migration hint: instead of the removed API, pass a custom function to `winston.format` (i.e. `winston.format(fn)`), which returns a Format transform usable in `format` option arrays.

Source

Thrown at lib/winston/common.js:26

'use strict';

const { format } = require('util');

/**
 * Set of simple deprecation notices and a way to expose them for a set of
 * properties.
 * @type {Object}
 * @private
 */
exports.warn = {
  deprecated(prop) {
    return () => {
      throw new Error(format('{ %s } was removed in winston@3.0.0.', prop));
    };
  },
  useFormat(prop) {
    return () => {
      throw new Error([
        format('{ %s } was removed in winston@3.0.0.', prop),
        'Use a custom winston.format = winston.format(function) instead.'
      ].join('\n'));
    };
  },
  forFunctions(obj, type, props) {
    props.forEach(prop => {
      obj[prop] = exports.warn[type](prop);
    });
  },
  forProperties(obj, type, props) {
    props.forEach(prop => {
      const notice = exports.warn[type](prop);
      Object.defineProperty(obj, prop, {
        get: notice,
        set: notice
      });
    });

View on GitHub (pinned to ff0b79de85)

Solutions

  1. Rewrite the removed formatter as a winston 3 custom format: `const myFormat = winston.format((info) => { /* mutate info */ return info; })()` and add it to the logger's `format` array.
  2. Use built-in winston 3 formats (`format.printf`, `format.combine`, `format.json`, `format.cli`) to replace the v2 helper.
  3. Consult UPGRADE-3.0.md for the specific `{ prop }` named in the message.
  4. Temporarily pin winston ^2.4.x if migration is not feasible now.

Example fix

// before (winston 2.x)
const logger = new winston.Logger({
  formatter: (options) => options.level + ': ' + options.message
});

// after (winston 3.x)
const logger = winston.createLogger({
  format: winston.format.combine(
    winston.format((info) => { info.output = info.level + ': ' + info.message; return info; })(),
    winston.format.printf((info) => info.output)
  ),
  transports: [new winston.transports.Console()]
});
Defensive patterns

Strategy: validation

Validate before calling

if (typeof legacyFormatter === 'function' && !/^\s*\(?(info|\{)/.test(legacyFormatter.toString())) {
  console.warn('v2 formatter signature detected; rewrite as winston.format(fn)');
}

Type guard

function isFormatTransform(f) { return f && typeof f === 'object' && typeof f.transform === 'function'; }

Try / catch

try {
  createLoggerWithLegacyFormat();
} catch (err) {
  if (err.message.includes('winston.format(function)')) {
    logger = winston.createLogger({ format: winston.format(legacyFn)(), transports });
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling a removed winston 2.x formatting-related function registered via `warn.useFormat(prop)` — e.g. legacy formatter helpers or logger-level format options that were folded into the `winston.format` pipeline in 3.0.0.

Common situations: Migrating winston 2.x code that used `formatter:` options or `winston.formatters.*` helpers; old docs/tutorials showing v2 custom formatting; plugins built against the v2 formatter signature.

Related errors


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