cube-js/cube · error · UserError
Can't parse date: '${to}'
Error message
Can't parse date: '${to}' What it means
Same as the 'from' check: in a 'from X to Y' date-range string, the 'to' half failed chrono-node parsing so dateParser throws this UserError. Cube requires both halves of the range to resolve to concrete dates to build the query time range.
Source
Thrown at packages/cubejs-api-gateway/src/date-parser.js:81
momentRange = [
moment.tz(timezone).startOf('day').add(1, 'day'),
moment.tz(timezone).endOf('day').add(1, 'day')
];
} else if (dateString.match(/^from (.*) to (.*)$/)) {
let [, from, to] = dateString.match(/^from(.{0,50})to(.{0,50})$/);
from = from.trim();
to = to.trim();
const current = moment(now).tz(timezone);
const fromResults = parse(from.trim(), new Date(current.format(moment.HTML5_FMT.DATETIME_LOCAL_MS)));
const toResults = parse(to.trim(), new Date(current.format(moment.HTML5_FMT.DATETIME_LOCAL_MS)));
if (!Array.isArray(fromResults) || !fromResults.length) {
throw new UserError(`Can't parse date: '${from}'`);
}
if (!Array.isArray(toResults) || !toResults.length) {
throw new UserError(`Can't parse date: '${to}'`);
}
const exactGranularity = ['second', 'minute', 'hour'].find(g => dateString.indexOf(g) !== -1) || 'day';
momentRange = [
momentFromResult(fromResults[0].start, timezone),
momentFromResult(toResults[0].start, timezone)
];
momentRange = [momentRange[0].startOf(exactGranularity), momentRange[1].endOf(exactGranularity)];
} else {
const current = moment(now).tz(timezone);
const results = parse(dateString, new Date(current.format(moment.HTML5_FMT.DATETIME_LOCAL_MS)));
if (!results?.length) {
throw new UserError(`Can't parse date: '${dateString}'`);
}
const exactGranularity = ['second', 'minute', 'hour'].find(g => dateString.indexOf(g) !== -1) || 'day';View on GitHub (pinned to 7d981676b3)
Solutions
- Fix the string after 'to' (shown in the error) to a chrono-parseable date, e.g. 'to 2024-02-28' or 'to now'
- Use built-in relative ranges ('last month', 'today') or explicit ISO arrays ['2024-01-01','2024-01-31'] instead
- Validate the end date with chrono-node in the client before sending the query
- If the end date can be empty, substitute the current date server-side before calling the API
Example fix
// before
{ dateRange: ['from last week to till now'] }
// after
{ dateRange: ['from last week to now'] } Defensive patterns
Strategy: validation
Validate before calling
import { parse } from 'chrono-node';
const m = range.match(/^from(.{0,50})to(.{0,50})$/i);
const to = m ? m[2].trim() : '';
if (!parse(to).length) throw new Error(`Invalid 'to' date in range: '${to}'`); Type guard
const isParseableToDate = (s) => typeof s === 'string' && /^from(.{0,50})to(.{0,50})$/i.test(s) && chronoParse(s.match(/^from(.{0,50})to(.{0,50})$/i)[2].trim()).length > 0; Try / catch
try {
await cube.load({ ...query, dateRange: [from, to] });
} catch (e) {
if (e instanceof Error && e.message.startsWith("Can't parse date:")) {
console.error(`Invalid range end ${e.message}`);
} else throw e;
} Prevention
- Validate both halves of 'from ... to ...' strings with chrono-node
- Default missing end dates to the current date instead of sending empty strings
- Use ISO date arrays for programmatic ranges
- Keep end-date inputs in UIs constrained to date pickers, not free text
When it happens
Trigger: dateRange entry like ['from last week to whenever'], ['from today to 2024-13-99'], or any string after 'to' that chrono-node cannot interpret (empty string, misspelled month, unsupported locale format).
Common situations: Dynamic filter UIs where the end-date field is empty or contains a free-text placeholder; locale-formatted dates produced with toLocaleDateString in non-US formats; typo'd or truncated strings concatenated into 'from ... to ...'.
Related errors
- Can't parse date: '${from}'
- Can't parse date: '${dateString}'
- Cannot parse selector date range ${selector.dateRange}
- Invalid Job query format: ${error.message || error.toString(
- provide --file <path> or --content <text>
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/3f92c29e3442abb5.
Report an issue: GitHub.