Infinite loop when year property is set as a string type (e.g., '2026' instead of 2026)

Author: iflovCreated Jan 8, 2026Updated Jun 27, 2026

Description

When setting the year property of a RecurrenceRule as a string (e.g., '2026') instead of a number (e.g., 2026), the _nextInvocationDate function enters an infinite loop, causing the server to hang indefinitely.

Steps to Reproduce

javascript
const schedule = require('node-schedule');

const rule = new schedule.RecurrenceRule();
rule.year = '2026';  // ❌ String type causes infinite loop
rule.month = 0;
rule.date = 1;
rule.hour = 0;
rule.minute = 0;
rule.second = 0;

// This will hang indefinitely
const job = schedule.scheduleJob(rule, function() {
    console.log('Happy New Year 2026!');
});

Expected Behavior

The library should either:

  1. Accept string values and internally convert them to numbers, OR
  2. Throw a clear validation error indicating that the year property must be a number type

Actual Behavior

The server hangs in an infinite loop with no error message.

Root Cause Analysis

The issue is in the _nextInvocationDate function in lib/Invocation.js:

javascript
// Line 151
if ((typeof this.year == 'number') && (this.year < fullYear)) {
    return null;
}

When year is set as a string (e.g., '2026'), the condition typeof this.year == 'number' evaluates to false, so the escape condition never triggers.

This causes the date calculation loop to continue incrementing past the target year without ever returning null, resulting in an infinite loop.

Suggested Fix

Option 1: Add type coercion in the setter or validation logic:

javascript
if (typeof this.year === 'string') {
    this.year = parseInt(this.year, 10);
}

Option 2: Fix the escape condition to handle both types:

javascript
const yearValue = Number(this.year);
if (!isNaN(yearValue) && yearValue < fullYear) {
    return null;
}

Environment

  • node-schedule version: 2.1.1
  • Node.js version: 20.x
  • OS: macOS

Related Issues

  • #495 (Infinite loop issue with similar symptoms)

Workaround

Ensure the year property is always set as a number:

javascript
// ✅ Correct usage
rule.year = 2026;
rule.year = Number('2026');
rule.year = parseInt('2026', 10);

Source: node-schedule/node-schedule