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
logger.profile(id, ...args) in winston v3 logs a duration message itself and no longer accepts a completion callback. For backwards compatibility, if the second-to-last argument is a function, winston warns 'Callback function no longer supported as of winston@3.0.0', pops it off the args, and continues without invoking it. This is a migration warning, not a thrown error.
Source
Thrown at lib/winston/logger.js:589
}
/**
* Tracks the time inbetween subsequent calls to this method with the same
* `id` parameter. The second call to this method will log the difference in
* milliseconds along with the message.
* @param {string} id Unique id of the profiler
* @returns {Logger} - TODO: add return description.
*/
profile(id, ...args) {
const time = Date.now();
if (this.profilers[id]) {
const timeEnd = this.profilers[id];
delete this.profilers[id];
// Attempt to be kind to users if they are still using older APIs.
if (typeof args[args.length - 2] === 'function') {
// eslint-disable-next-line no-console
console.warn(
'Callback function no longer supported as of winston@3.0.0'
);
args.pop();
}
// Set the duration property of the metadata
const info = typeof args[args.length - 1] === 'object' ? args.pop() : {};
info.level = info.level || 'info';
info.durationMs = time - timeEnd;
info.message = info.message || id;
return this.write(info);
}
this.profilers[id] = time;
return this;
}
/**View on GitHub (pinned to ff0b79de85)
Solutions
- Remove the callback; winston v3 profile() emits the completion log event itself — listen via logger.on('logging') or a profile callback-free flow.
- Use explicit timing instead: const start = Date.now(); ...; logger.info('msg', { durationMs: Date.now() - start }).
- If you need programmatic completion, use logger.startTimer() / profiler.done(info) API of winston v3.
Example fix
// before
logger.profile('db-query', (err, level, msg, meta) => { console.log('done'); });
// after
logger.profile('db-query'); // completion logged automatically on profiler.done
// or
const profiler = logger.startTimer();
profiler.done({ message: 'db-query finished' }); Defensive patterns
Strategy: try-catch
Validate before calling
function safeProfile(logger, id, ...args) {
const filtered = args.filter(a => typeof a !== 'function');
return logger.profile(id, ...filtered);
} Type guard
const usesLegacyProfileCallback = (...args) => typeof args[args.length - 2] === 'function';
Prevention
- Drop callbacks from profile() calls when migrating to winston v3+.
- Use logger.startTimer() / profiler.done() for programmatic timing completion.
- Listen for the deprecation warning in logs during upgrade testing.
When it happens
Trigger: Calling logger.profile('id', callback) or logger.profile('id', info, callback) — any profile() call whose args[len-2] is a function, i.e. winston v2-style profiling code run on winston v3+.
Common situations: Upgrading from winston 2.x to 3.x and keeping old profiler code that relied on the callback to time operations; copy-pasted legacy timing helpers.
Related errors
- { %s } was removed in winston@3.0.0.
- { %s } was removed in winston@3.0.0. Use a custom winston.fo
- { colors, emitErrs, formatters, padLevels, rewriters, stripC
- Logger.cli() was removed in winston@3.0.0 Use a custom winst
- Deprecated: .handleExceptions() will be removed in winston@4
AI-assisted analysis of winstonjs/winston@ff0b79de85 (2026-08-31).
Data as JSON: /api/errors/c25f866f3c88f701.
Report an issue: GitHub.