{"record":{"id":"be3fd4aa50d34923","repo":"cube-js/cube","slug":"invalid-interval-interval","errorCode":null,"errorMessage":"Invalid interval: ${interval}","messagePattern":"Invalid interval: (.+?)","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":5021,"sourceCode":"    ) {\n      return 'minute';\n    } else if (\n      obj.milliseconds === 0\n    ) {\n      return 'second';\n    }\n    return 'second'; // TODO return 'millisecond';\n  }\n\n  /**\n   * @protected\n   * @param {string} interval\n   * @return {[number, string]}\n   */\n  parseInterval(interval) {\n    const intervalMatch = interval.match(/^(-?\\d+) (second|minute|hour|day|week|month|quarter|year)s?$/);\n    if (!intervalMatch) {\n      throw new UserError(`Invalid interval: ${interval}`);\n    }\n\n    const duration = parseInt(intervalMatch[1], 10);\n\n    return [duration, intervalMatch[2]];\n  }\n\n  negateInterval(interval) {\n    const [duration, grunularity] = this.parseInterval(interval);\n\n    return `${duration * -1} ${grunularity}`;\n  }\n\n  parseSecondDuration(interval) {\n    const [duration, type] = this.parseInterval(interval);\n\n    const secondsInInterval = SecondsDurations[type];\n    return secondsInInterval * duration;","sourceCodeStart":5003,"sourceCodeEnd":5039,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L5003-L5039","documentation":"parseInterval expects a string of the form '<number> <unit>' where unit is one of second(s), minute(s), hour(s), day(s), week(s), month(s), quarter(s), year(s) — e.g. '1 hour'. Any string not matching the regex throws this UserError.","triggerScenarios":"Passing 'hour', '1h', '60 minutes and 30 seconds', '1 Hour' with odd casing is fine? — actually casing is fixed: e.g. every: '2 days ' with trailing content, or refreshKeyRenewalThreshold receiving 'PT1H' ISO-8601 durations.","commonSituations":"Using ISO-8601 duration strings ('PT10M') instead of '<n> <unit>'; missing the number ('hour'); pluralization/unit typos ('fortnight', 'hr'); passing a number instead of string in JS configs.","solutions":["Rewrite the interval as '<integer> <unit>' with unit in second/minute/hour/day/week/month/quarter/year, e.g. '10 minutes'","Convert ISO-8601 durations to the Cube form ('PT1H' -> '1 hour')","Ensure the value is a string, not a number or object"],"exampleFix":"// before\nrefreshKey: { every: 'PT1H' }\n// after\nrefreshKey: { every: '1 hour' }","handlingStrategy":"validation","validationCode":"const RE = /^(-?\\d+) (second|minute|hour|day|week|month|quarter|year)s?$/;\nfunction validateInterval(interval) { if (!RE.test(String(interval))) throw new Error(`Invalid interval: ${interval}`); }","typeGuard":"const isValidInterval = (v) => typeof v === 'string' && /^(-?\\d+) (second|minute|hour|day|week|month|quarter|year)s?$/.test(v);","tryCatchPattern":"try { await cubeApi.query(q); } catch (e) { if (/Invalid interval:/.test(e.message)) console.error('Use \"<n> <unit>\" form, e.g. \"1 hour\"'); throw e; }","preventionTips":["Always format intervals as '<integer> <unit>'","Never use ISO-8601 durations (PT1H) in Cube configs","Quote units fully (hour not hr) and keep the number and unit space-separated"],"tags":["interval","refresh-key","validation"],"backgroundTag":"invalid-interval-format","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}