chartjs/Chart.js · error · Error

${min} and ${max} are too far apart with stepSize of ${stepS

Error message

${min} and ${max} are too far apart with stepSize of ${stepSize} ${minor}

What it means

TimeScale._generate() builds ticks by stepping from min to max in increments of stepSize on the minor unit using adapter.add. To prevent the browser from freezing when options would produce millions of ticks, it caps the span at adapter.diff(max, min, minor) > 100000 * stepSize and throws, reporting the min, max, stepSize, and unit. This is a deliberate guard against pathological time-axis configurations.

Source

Thrown at src/scales/scale.time.js:475

    const minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min));
    const stepSize = valueOrDefault(options.ticks.stepSize, 1);
    const weekday = minor === 'week' ? timeOpts.isoWeekday : false;
    const hasWeekday = isNumber(weekday) || weekday === true;
    const ticks = {};
    let first = min;
    let time, count;

    // For 'week' unit, handle the first day of week option
    if (hasWeekday) {
      first = +adapter.startOf(first, 'isoWeek', weekday);
    }

    // Align first ticks on unit
    first = +adapter.startOf(first, hasWeekday ? 'day' : minor);

    // Prevent browser from freezing in case user options request millions of milliseconds
    if (adapter.diff(max, min, minor) > 100000 * stepSize) {
      throw new Error(min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor);
    }

    const timestamps = options.ticks.source === 'data' && this.getDataTimestamps();
    for (time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++) {
      addTick(ticks, time, timestamps);
    }

    if (time === max || options.bounds === 'ticks' || count === 1) {
      addTick(ticks, time, timestamps);
    }

    // @ts-ignore
    return Object.keys(ticks).sort(sorter).map(x => +x);
  }

  /**
	 * @param {number} value
	 * @return {string}

View on GitHub (pinned to cb02e1d207)

Solutions

  1. Increase ticks.stepSize so that (max-min)/stepSize stays well under 100000 (e.g. set stepSize: 7 with unit 'day' for weekly ticks over years).
  2. Set an explicit, coarser time.unit (e.g. 'month' or 'year') so each step covers more time.
  3. Filter/clamp outlier timestamps so min and max reflect the real data window.
  4. Set time.min/time.max to bound the visible range, reducing adapter.diff(max, min, minor).

Example fix

// before
options: {
  scales: { x: { type: 'time', time: { unit: 'second' } } }
} // years of data, stepSize defaults to 1 -> throws

// after
options: {
  scales: { x: { type: 'time', time: { unit: 'week' }, ticks: { stepSize: 1 } } }
}
Defensive patterns

Strategy: validation

Validate before calling

// Estimate the tick count and refuse configs that would exceed Chart.js' guard.
function validateTimeRange(minMs, maxMs, unit, stepSize) {
  const msPerUnit = {
    millisecond: 1, second: 1000, minute: 60000, hour: 3600000,
    day: 86400000, week: 604800000, month: 2592000000, year: 31536000000
  };
  const per = msPerUnit[unit] || 1;
  const steps = (maxMs - minMs) / (per * (stepSize || 1));
  if (steps > 100000) {
    throw new Error(
      `Time range too large: ~${Math.round(steps)} ticks. Increase ticks.stepSize or use a coarser time.unit.`
    );
  }
}
validateTimeRange(minTimestamp, maxTimestamp, 'second', 1);

Try / catch

// Catch the guard during development and surface a clearer config message.
try {
  chart.update();
} catch (e) {
  if (/too far apart/i.test(String(e?.message))) {
    console.error('Time axis span too large for current stepSize/unit. Coarsen time.unit or raise ticks.stepSize.', e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: A very wide data range (e.g. years of millisecond data) combined with a small time.unit and a small ticks.stepSize (default stepSize = 1), so 100000*stepSize ticks would be generated; explicitly setting ticks.stepSize to a tiny number on a multi-year range; unit auto-picking a fine unit (millisecond/second) on a huge range.

Common situations: Plotting a time series spanning years with stepSize left at default 1; data with one outlier timestamp far in the future/past stretching min/max; misconfigured ticks.stepSize in seconds over a multi-year dataset; mixing units where time.unit is forced to a small value.

Related errors


AI-assisted analysis of chartjs/Chart.js@cb02e1d207 (2026-08-12). Data as JSON: /api/errors/d596f0f9736ac725. Report an issue: GitHub.