mantinedev/mantine · error · Error

[@mantine/schedule] MonthView: Duplicated event ids found: $

Error message

[@mantine/schedule] MonthView: Duplicated event ids found: ${event.id}

What it means

MonthView validates that each event id is unique while filtering events for the displayed month. A duplicate id among the month's events throws this error during render, since ids drive positioning and interactions in the month grid.

Source

Thrown at packages/@mantine/schedule/src/components/MonthView/get-month-view-events/get-month-view-events.ts:49

    return { groupedByDay: {}, groupedByWeek: {}, backgroundByWeek: {} };
  }

  const ids = new Set<string | number>();
  const filteredEvents: ScheduleEventData[] = [];

  const range = getMonthRange({ month: date, withOutsideDays, consistentWeeks, firstDayOfWeek });

  for (const event of events) {
    if (
      dayjs(event.end).isAfter(range.start, 'day') ||
      dayjs(event.start).isBefore(range.end, 'day')
    ) {
      filteredEvents.push(validateEvent(event));

      if (!ids.has(event.id)) {
        ids.add(event.id);
      } else {
        throw new Error(`[@mantine/schedule] MonthView: Duplicated event ids found: ${event.id}`);
      }
    }
  }

  return getMonthPositionedEvents({
    date,
    events: filteredEvents,
    firstDayOfWeek,
    range,
  });
}

View on GitHub (pinned to 8a284e2c2c)

Solutions

  1. Give each occurrence a unique id (e.g. `${event.id}-${start}`)
  2. Deduplicate by id before rendering
  3. Fix the API/caching layer that yields duplicates

Example fix

// before
const events = series.map((occ) => ({ ...occ, id: seriesId }));

// after
const events = series.map((occ) => ({ ...occ, id: `${seriesId}-${occ.start}` }));
Defensive patterns

Strategy: validation

Validate before calling

const withOccurrenceIds = (series) =>
  series.map((occ) => ({ ...occ, id: `${occ.seriesId ?? occ.id}-${occ.start}` }));

<Schedule events={withOccurrenceIds(allEvents)} view="month" />;

Type guard

function hasUniqueEventIds(events: { id: string | number }[]): boolean {
  return new Set(events.map((e) => e.id)).size === events.length;
}

Prevention

When it happens

Trigger: Two events sharing the same id in the events prop when a month view is displayed; duplicated records from an API; recurring events expanded into instances that all keep the series id.

Common situations: Recurring event series where every occurrence keeps the series id; concatenating calendar feeds; caching layers returning stale plus fresh copies of the same event.

Related errors


AI-assisted analysis of mantinedev/mantine@8a284e2c2c (2026-08-28). Data as JSON: /api/errors/078724dc9fd81827. Report an issue: GitHub.