{"record":{"id":"c25f866f3c88f701","repo":"winstonjs/winston","slug":"callback-function-no-longer-supported-as-of-winsto","errorCode":null,"errorMessage":"Callback function no longer supported as of winston@3.0.0","messagePattern":"Callback function no longer supported as of winston@3\\.0\\.0","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/winston/logger.js","lineNumber":589,"sourceCode":"  }\n\n  /**\n   * Tracks the time inbetween subsequent calls to this method with the same\n   * `id` parameter. The second call to this method will log the difference in\n   * milliseconds along with the message.\n   * @param {string} id Unique id of the profiler\n   * @returns {Logger} - TODO: add return description.\n   */\n  profile(id, ...args) {\n    const time = Date.now();\n    if (this.profilers[id]) {\n      const timeEnd = this.profilers[id];\n      delete this.profilers[id];\n\n      // Attempt to be kind to users if they are still using older APIs.\n      if (typeof args[args.length - 2] === 'function') {\n        // eslint-disable-next-line no-console\n        console.warn(\n          'Callback function no longer supported as of winston@3.0.0'\n        );\n        args.pop();\n      }\n\n      // Set the duration property of the metadata\n      const info = typeof args[args.length - 1] === 'object' ? args.pop() : {};\n      info.level = info.level || 'info';\n      info.durationMs = time - timeEnd;\n      info.message = info.message || id;\n      return this.write(info);\n    }\n\n    this.profilers[id] = time;\n    return this;\n  }\n\n  /**","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/winstonjs/winston/blob/ff0b79de8562bb322c390fbc82fe71c11f373428/lib/winston/logger.js#L571-L607","documentation":"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.","triggerScenarios":"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+.","commonSituations":"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.","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."],"exampleFix":"// before\nlogger.profile('db-query', (err, level, msg, meta) => { console.log('done'); });\n// after\nlogger.profile('db-query'); // completion logged automatically on profiler.done\n// or\nconst profiler = logger.startTimer();\nprofiler.done({ message: 'db-query finished' });","handlingStrategy":"try-catch","validationCode":"function safeProfile(logger, id, ...args) {\n  const filtered = args.filter(a => typeof a !== 'function');\n  return logger.profile(id, ...filtered);\n}","typeGuard":"const usesLegacyProfileCallback = (...args) => typeof args[args.length - 2] === 'function';","tryCatchPattern":null,"preventionTips":["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."],"tags":["winston","profile","breaking-change","migration"],"backgroundTag":"removed-callback-api","analyzedSha":"ff0b79de8562bb322c390fbc82fe71c11f373428","analyzedAt":"2026-08-31T13:33:44.585Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}