winstonjs/winston · warning
Callback function no longer supported as of winston@3.0.0
Error message
Callback function no longer supported as of winston@3.0.0
What it means
winston's Profiler.done() warns when its final argument is a function. In winston 2.x you could pass a callback that received the finished profile log; winston 3.0.0 removed callback support across the logging API, so the callback is silently popped and ignored, and this warning is printed.
Source
Thrown at lib/winston/profiler.js:41
const Logger = require('./logger');
if (typeof logger !== 'object' || Array.isArray(logger) || !(logger instanceof Logger)) {
throw new Error('Logger is required for profiling');
} else {
this.logger = logger;
this.start = Date.now();
}
}
/**
* Ends the current timer (i.e. Profiler) instance and logs the `msg` along
* with the duration since creation.
* @returns {mixed} - TODO: add return description.
* @private
*/
done(...args) {
if (typeof args[args.length - 1] === 'function') {
// eslint-disable-next-line no-console
console.warn('Callback function no longer supported as of winston@3.0.0');
args.pop();
}
const info = typeof args[args.length - 1] === 'object' ? args.pop() : {};
info.level = info.level || 'info';
info.durationMs = (Date.now()) - this.start;
return this.logger.write(info);
}
}
module.exports = Profiler;
View on GitHub (pinned to ff0b79de85)
Solutions
- Remove the callback argument from done() and rely on the profiler emitting its own info-level log entry.
- Attach a transport or listen to the logger 'logging' event to observe the completed profile log instead of using a callback.
- Use logger.profile(id) callback form where supported, or log manually with info.durationMs from the emitted meta.
Example fix
// before
const timer = logger.startTimer();
timer.done('message', function (err, level, msg, meta) { ... });
// after
const timer = logger.startTimer();
timer.done('message');
// observe via transports / logger events instead of a callback Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure no function is passed to Profiler.done
function assertNoCallback(args) {
if (args.length && typeof args[args.length - 1] === 'function') {
throw new TypeError('Profiler.done no longer accepts a callback (winston >= 3). Remove it.');
}
} Type guard
function hasTrailingCallback(args) {
return args.length > 0 && typeof args[args.length - 1] === 'function';
} Prevention
- Do not pass callbacks to any winston 3.x logging/profiling method.
- Consume profile results via transports or the logger 'logging' event.
- Type your logger wrapper so timer.done() has no callback parameter.
When it happens
Trigger: Calling logger.startTimer().done(function(err, level, msg, meta){ ... }) or var profiler = logger.profile('x'); profiler.done(callback) — passing a function as the last argument to done().
Common situations: Migrating winston 2.x profiling code to 3.x; examples from older blog posts showing profile timers with completion callbacks.
Related errors
- { %s } was removed in winston@3.0.0.
- { %s } was removed in winston@3.0.0. Use a custom winston.fo
- Logger.cli() was removed in winston@3.0.0 Use a custom winst
- Logger is required for profiling
- Deprecated: .handleExceptions() will be removed in winston@4
AI-assisted analysis of winstonjs/winston@ff0b79de85 (2026-08-31).
Data as JSON: /api/errors/3174f15013b4e3d1.
Report an issue: GitHub.