node-cron icon indicating copy to clipboard operation
node-cron copied to clipboard

`noOverlap` blocks new runs even after async task finishes

Open NivGreenstein opened this issue 2 weeks ago • 0 comments

Summary

When using noOverlap: true with an async task, node-cron continues to log that the task is still running and keeps blocking new executions, even though the async function has already finished and my own code logs an exit message.

Code

import { schedule as cronSchedule } from 'node-cron';

const scheduledTask = cronSchedule(
  appConfig.cron!.expression,
  async () => {
    const { error } = await tryCatch(startJob());

    if (error) {
      logger.error({ msg: 'Error during job', error, failurePenaltySeconds });
      await delay(failurePenaltySeconds);
    }

    console.log('finished async function');
  },
  {
    noOverlap: true,
  }
);

Cron expression: */10 * * * * *

Logs

{"level":"info","time":1765385331754,"pid":18,"msg":"exiting safely","exitCode":0}
finished async function
[2025-12-10T16:49:00.010Z] [PID: 18] [NODE-CRON] [WARN] task still running, new execution blocked by overlap prevention!
[2025-12-10T16:49:10.001Z] [PID: 18] [NODE-CRON] [WARN] task still running, new execution blocked by overlap prevention!
[2025-12-10T16:49:20.002Z] [PID: 18] [NODE-CRON] [WARN] task still running, new execution blocked by overlap prevention!
...
[2025-12-10T16:50:50.003Z] [PID: 18] [NODE-CRON] [WARN] task still running, new execution blocked by overlap prevention!

The JSON log

{"level":"info","time":1765385331754,"pid":18,"msg":"exiting safely","exitCode":0}

is emitted from inside startJob(). After that, my code logs finished async function, so from my side the Promise chain has completed. However, node-cron still thinks the task is running and continues to block future executions because of noOverlap.

Questions / debugging attempts

I’m currently not sure how to debug this further. A few questions:

  • Is there any known limitation or caveat with noOverlap and async functions (or Promises) that I might be missing?
  • Does node-cron expect a specific pattern (e.g. returning the Promise explicitly instead of using async / await), or any other configuration for noOverlap to work correctly with async tasks?
  • Is there any way to introspect / reset the internal state that tracks whether a task is “still running”?

If there’s anything obvious I’m doing wrong, I’d really appreciate pointers. I’m also happy to try out any debugging steps or extra logging if that would help.

Environment

  • node-cron version: 4.1.0
  • Node.js version v20.19.0
  • OS: Debian GNU/Linux 12 (bookworm)
  • Runtime context: Docker container (node:20.19.0-slim as base image)

NivGreenstein avatar Dec 10 '25 17:12 NivGreenstein