RocketChat/Rocket.Chat · error · Error

invalid ISO 8601 date

Error message

invalid ISO 8601 date

What it means

Thrown by mapDateForAPI (engagementDashboard/date.ts) when the input string fails isDateISOString — a memoized validator that requires both Date.parse to succeed AND new Date(ts).toISOString() to round-trip exactly back to the input. Plain Error. This is intentionally strict: '2021-01-01' or '2021/01/01' will fail because they do not match the full toISOString output.

Source

Thrown at apps/meteor/ee/server/lib/engagementDashboard/date.ts:14

import mem from 'mem';
import moment from 'moment';

export const isDateISOString = mem(
	(input: string): input is string => {
		const timestamp = Date.parse(input);
		return !Number.isNaN(timestamp) && new Date(timestamp).toISOString() === input;
	},
	{ maxAge: 10000 },
);

export const mapDateForAPI = (input: string): Date => {
	if (!isDateISOString(input)) {
		throw new Error('invalid ISO 8601 date');
	}

	return new Date(Date.parse(input));
};

export const convertDateToInt = (date: Date): number => parseInt(moment(date).clone().format('YYYYMMDD'), 10);
export const convertIntToDate = (intValue: number): Date => moment(intValue, 'YYYYMMDD').clone().toDate();
const diffBetweenDays = (start: string | number | Date, end: string | number | Date): number =>
	moment(new Date(start)).clone().diff(new Date(end), 'days');
export const diffBetweenDaysInclusive = (start: string | number | Date, end: string | number | Date): number =>
	diffBetweenDays(start, end) + 1;

export const getTotalOfWeekItems = <T extends Record<string, number>>(weekItems: T[], property: keyof T): number =>
	weekItems.reduce((acc, item) => {
		acc += item[property];
		return acc;
	}, 0);

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Send the date as a full UTC ISO string produced by new Date(...).toISOString() (e.g. '2021-06-01T00:00:00.000Z').
  2. On the caller, normalize with moment(date).toISOString() before hitting the API.
  3. If only a date is meaningful, expand it to start-of-day UTC on the client.

Example fix

// before
mapDateForAPI('2021-06-01');          // throws
mapDateForAPI('06/01/2021 00:00');     // throws

// after
mapDateForAPI(new Date('2021-06-01').toISOString()); // '2021-06-01T00:00:00.000Z'
Defensive patterns

Strategy: validation

Validate before calling

function toApiDate(input: string | Date): string {
  const iso = input instanceof Date ? input.toISOString() : new Date(input).toISOString();
  if (!isDateISOString(iso)) throw new Error('invalid ISO 8601 date');
  return iso;
}

Type guard

const isISODate = (s: unknown): s is string =>
  typeof s === 'string' && !Number.isNaN(Date.parse(s)) && new Date(Date.parse(s)).toISOString() === s;

Try / catch

try { mapDateForAPI(input); } catch (e) {
  if (e instanceof Error && e.message === 'invalid ISO 8601 date') { /* normalize input with new Date(input).toISOString() and retry */ } else throw e;
}

Prevention

When it happens

Trigger: Calling the engagement dashboard API with a date that is not a full ISO 8601 timestamp in UTC 'Z' form — e.g. date-only, locale strings, millisecond/truncated variants, or strings that parse but do not round-trip identically.

Common situations: Client sends a YYYY-MM-DD value from a date picker; integration forwards a locale-formatted date; timezone offset included (e.g. '+00:00') so toISOString !== input; trailing spaces or non-ISO separators.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/7d8e322ee9149ac9. Report an issue: GitHub.