{"record":{"id":"f7eac71427ee053d","repo":"cube-js/cube","slug":"can-t-parse-date-from","errorCode":null,"errorMessage":"Can't parse date: '${from}'","messagePattern":"Can't parse date: '(.+?)'","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-api-gateway/src/date-parser.js","lineNumber":77,"sourceCode":"      moment.tz(timezone).startOf('day').add(-1, 'day'),\n      moment.tz(timezone).endOf('day').add(-1, 'day')\n    ];\n  } else if (dateString.match(/tomorrow/)) {\n    momentRange = [\n      moment.tz(timezone).startOf('day').add(1, 'day'),\n      moment.tz(timezone).endOf('day').add(1, 'day')\n    ];\n  } else if (dateString.match(/^from (.*) to (.*)$/)) {\n    let [, from, to] = dateString.match(/^from(.{0,50})to(.{0,50})$/);\n    from = from.trim();\n    to = to.trim();\n\n    const current = moment(now).tz(timezone);\n    const fromResults = parse(from.trim(), new Date(current.format(moment.HTML5_FMT.DATETIME_LOCAL_MS)));\n    const toResults = parse(to.trim(), new Date(current.format(moment.HTML5_FMT.DATETIME_LOCAL_MS)));\n\n    if (!Array.isArray(fromResults) || !fromResults.length) {\n      throw new UserError(`Can't parse date: '${from}'`);\n    }\n\n    if (!Array.isArray(toResults) || !toResults.length) {\n      throw new UserError(`Can't parse date: '${to}'`);\n    }\n\n    const exactGranularity = ['second', 'minute', 'hour'].find(g => dateString.indexOf(g) !== -1) || 'day';\n    momentRange = [\n      momentFromResult(fromResults[0].start, timezone),\n      momentFromResult(toResults[0].start, timezone)\n    ];\n\n    momentRange = [momentRange[0].startOf(exactGranularity), momentRange[1].endOf(exactGranularity)];\n  } else {\n    const current = moment(now).tz(timezone);\n    const results = parse(dateString, new Date(current.format(moment.HTML5_FMT.DATETIME_LOCAL_MS)));\n\n    if (!results?.length) {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-api-gateway/src/date-parser.js#L59-L95","documentation":"dateParser handles a 'from X to Y' date-range string from a query's dateRange parameter. The 'from' half is parsed with chrono-node; when chrono returns no results the library throws this UserError because the string is not a recognized natural-language or fixed date expression. Cube throws it instead of silently producing a broken time range for the query.","triggerScenarios":"Calling the /cubejs-system/v1 or /load REST API with a dateRange entry matching /^from (.*) to (.*)$/ where the text after 'from' cannot be parsed by chrono-node, e.g. dateRange: ['from 32/45/2024 to next week'], ['from someday to today'], or a locale-specific format like 'from 01.02.2024 to 05.02.2024' that chrono misreads.","commonSituations":"Passing non-English date strings; passing strict formats like ISO 'YYYY-MM-DD' inside a 'from ... to ...' wrapper that chrono fails on (note plain ISO strings work in the else-branch); typos or placeholder values left in dashboard filter code; upgrading environments where chrono parsing behavior changed.","solutions":["Check the exact string between 'from' and 'to' in the error message and fix it to a chrono-node parseable expression, e.g. 'from yesterday to today' or 'from 2024-01-01 to 2024-01-31'","Use one of the built-in relative expressions instead: 'last week', 'last 7 days', 'today', 'yesterday', 'tomorrow'","Pass an explicit dateRange array of ISO strings like ['2024-01-01','2024-01-31'] rather than a 'from ... to ...' sentence","Pre-parse the range in client code with chrono-node to confirm it resolves before sending the query"],"exampleFix":"// before\n{ dateRange: ['from 01-31-2024 to 02-31-2024'] }\n// after\n{ dateRange: ['from 2024-01-31 to 2024-02-28'] }","handlingStrategy":"fallback","validationCode":"// Scan SQL for unsupported functions before sending to Cube SQL API\nfunction usesUnsupportedFn(sql) {\n  return /\\bDAYOFWEEK\\s*\\(/i.test(sql);\n}\nif (usesUnsupportedFn(sql)) throw new Error('DAYOFWEEK is not implemented in CubeSQL; rewrite the query');","typeGuard":"function isSupportedDateFn(fnName, supported = ['year','quarter','month','week','day','date_trunc']) {\n  return supported.includes(fnName.toLowerCase());\n}","tryCatchPattern":"try {\n  return await connection.query(sql);\n} catch (e) {\n  if (/Not implemented/.test(String(e.message))) {\n    return await connection.query(rewriteDayOfWeek(sql));\n  }\n  throw e;\n}","preventionTips":["Keep a list of CubeSQL-supported scalar functions and lint queries against it","Prefer EXTRACT/date_trunc style expressions over MySQL-specific date functions","Precompute date parts as dimensions in the data model","Track cubesql UDF stubs (todo! in rust/cubesql common.rs) before adopting new functions"],"tags":["date-parsing","user-input","rest-api","validation"],"backgroundTag":"unparseable-date-string","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}