pandas-dev/pandas · error · ValueError

Offset did not increment date

Error message

Offset {offset} did not increment date

What it means

Raised inside the date_range generator loop (datetime_to_seq) when applying `offset._apply(cur)` to the current timestamp does not advance it (next_date <= cur for positive offsets, or next_date >= cur for negative). This protects against infinite loops from pathological offsets whose n is zero or whose apply is a no-op for the given input.

Solutions

  1. Audit the offset: ensure `offset._apply(ts) > ts` for positive-n offsets on all relevant inputs.
  2. Avoid `n=0` offsets in date_range — they cannot produce a sequence; filter them out upstream.
  3. Switch to a built-in offset that is known to advance (e.g. `pd.offsets.Day(1)`).
  4. If using a custom calendar, add an explicit advance in `_apply` and unit-test it across month/year boundaries.

Example fix

// before
rng = pd.date_range(start, end, freq=pd.offsets.Day(0))

// after
rng = pd.date_range(start, end, freq=pd.offsets.Day(1))
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd

def offset_advances(offset, ts):
    nxt = offset._apply(ts)
    return nxt > ts if offset.n >= 0 else nxt < ts

def safe_date_range(start, end, freq):
    if getattr(freq, 'n', 1) == 0:
        raise ValueError('offset with n=0 cannot generate a range')
    return pd.date_range(start=start, end=end, freq=freq)

Type guard

def offset_is_progressing(offset, ts) -> bool:
    try:
        nxt = offset._apply(ts)
    except Exception:
        return False
    return nxt > ts if offset.n >= 0 else nxt < ts

Try / catch

try:
    rng = pd.date_range(start=start, end=end, freq=freq)
except ValueError as e:
    if 'did not increment date' in str(e) or 'did not decrement date' in str(e):
        raise ValueError(f'Offset {freq} is a no-op; choose an advancing offset') from e
    raise

Prevention

When it happens

Trigger: Calling `pd.date_range(start, end, freq=<custom offset that does not advance>)` with a custom DateOffset subclass whose `_apply` returns the same or earlier timestamp. Using an offset with `n=0` in a context that bypasses the n==0 fast path. Also reachable with offsets that round/truncate backward (e.g. some semi-month-end offsets near boundaries).

Common situations: User-defined DateOffset with a buggy `_apply`. Built-in offsets with `n=0` (e.g. `pd.offsets.Day(0)`). Edge cases in custom business calendars. Offsets that snap to month-end applied at month-end where the snap returns the same date.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/6e09afef0cf8532f. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/datetimes.py:3273

    start = cast("Timestamp", start)
    end = cast("Timestamp", end)

    cur = start
    if offset.n >= 0:
        while cur <= end:
            yield cur

            if cur == end:
                # GH#24252 avoid overflows by not performing the addition
                # in offset.apply unless we have to
                break

            # faster than cur + offset
            next_date = offset._apply(cur)
            next_date = next_date.as_unit(unit)
            if next_date <= cur:
                raise ValueError(f"Offset {offset} did not increment date")
            cur = next_date
    else:
        while cur >= end:
            yield cur

            if cur == end:
                # GH#24252 avoid overflows by not performing the addition
                # in offset.apply unless we have to
                break

            # faster than cur + offset
            next_date = offset._apply(cur)
            next_date = next_date.as_unit(unit)
            if next_date >= cur:
                raise ValueError(f"Offset {offset} did not decrement date")
            cur = next_date

View on GitHub (pinned to 3b7651241d)