winstonjs/winston · warning
winston: not exiting process.
Error message
winston: not exiting process.
What it means
Companion warning to the exitOnError message in RejectionHandler._unhandledRejection. Because there were no rejection handler transports, winston forces doExit = false and prints this warning to make clear the process will NOT exit despite exitOnError being true.
Source
Thrown at lib/winston/rejection-handler.js:181
* @param {Error} err - Error to handle
* @returns {mixed} - TODO: add return description.
* @private
*/
_unhandledRejection(err) {
const info = this.getAllInfo(err);
const handlers = this._getRejectionHandlers();
// Calculate if we should exit on this error
let doExit =
typeof this.logger.exitOnError === 'function'
? this.logger.exitOnError(err)
: this.logger.exitOnError;
let timeout;
if (!handlers.length && doExit) {
// eslint-disable-next-line no-console
console.warn('winston: exitOnError cannot be true with no rejection handlers.');
// eslint-disable-next-line no-console
console.warn('winston: not exiting process.');
doExit = false;
}
function gracefulExit() {
debug('doExit', doExit);
debug('process._exiting', process._exiting);
if (doExit && !process._exiting) {
// Remark: Currently ignoring any rejections from transports when
// catching unhandled rejections.
if (timeout) {
clearTimeout(timeout);
}
// eslint-disable-next-line no-process-exit
process.exit(1);
}
}
View on GitHub (pinned to ff0b79de85)
Solutions
- Register a rejection transport so rejections are logged and the exit path proceeds: logger.rejections.handle(transport).
- If surviving is acceptable, treat this as informational and add your own process.on('unhandledRejection') logging to avoid silent drops.
- Explicitly set exitOnError:false to acknowledge the intended behavior and remove confusion.
Example fix
// before
const logger = winston.createLogger({ exitOnError: true });
// (no rejection transports — process survives rejections)
// after
logger.rejections.handle(
new winston.transports.File({ filename: 'logs/unhandledRejections.log' })
); Defensive patterns
Strategy: fallback
Validate before calling
// Ensure the process still handles rejections the way you expect
process.on('unhandledRejection', (reason) => {
console.error('Unhandled rejection after winston no-op:', reason);
}); Try / catch
process.on('unhandledRejection', (reason) => {
logger.error('unhandled rejection', { reason: String(reason) });
if (shouldExitOnError) process.exit(1); // own exit policy as fallback
}); Prevention
- Register a rejection transport so winston can exit instead of swallowing rejections.
- Install a process-level unhandledRejection listener as a safety net.
- Monitor startup logs for the 'not exiting process' warning in production.
When it happens
Trigger: An unhandled promise rejection fires when the rejection handler has zero transports and doExit was initially true; after warning 'exitOnError cannot be true with no rejection handlers.', winston prints this second line and continues running.
Common situations: Same as error 22: logger configured with exitOnError true but no rejection transports; operators expecting the process to die on a bad rejection and a supervisor to restart it — the process instead survives with silently dropped rejections.
Related errors
- winston: exitOnError cannot be true with no rejection handle
- { colors, emitErrs, formatters, padLevels, rewriters, stripC
- { %s } was removed in winston@3.0.0.
- { %s } was removed in winston@3.0.0. Use a custom winston.fo
- Logger is required to handle exceptions
AI-assisted analysis of winstonjs/winston@ff0b79de85 (2026-08-31).
Data as JSON: /api/errors/7be2bd4f1ae94c4c.
Report an issue: GitHub.