{"record":{"id":"28fec0f59a6ade6e","repo":"cube-js/cube","slug":"options-timestampprecision-is-required-actual","errorCode":null,"errorMessage":"options.timestampPrecision is required, actual: ${options.timestampPrecision}","messagePattern":"options\\.timestampPrecision is required, actual: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-backend-shared/src/time.ts","lineNumber":246,"sourceCode":"      alignedStart.clone()\n        .subtract(1, 'second')\n        .format(`YYYY-MM-DDTHH:mm:ss.${'9'.repeat(options.timestampPrecision)}`)\n    ]);\n  }\n\n  return dates;\n};\n\n/**\n * Returns array of date ranges for a predefined granularity aligned with the start of the year as pivot point\n */\nexport const timeSeries = (granularity: string, dateRange: QueryDateRange, options: TimeSeriesOptions = { timestampPrecision: 3 }): QueryDateRange[] => {\n  if (!TIME_SERIES[granularity]) {\n    throw new Error(`Unsupported time granularity: ${granularity}`);\n  }\n\n  if (!options.timestampPrecision) {\n    throw new Error(`options.timestampPrecision is required, actual: ${options.timestampPrecision}`);\n  }\n\n  checkSeriesForDateRange(`1 ${granularity}`, dateRange);\n\n  // moment.range works with strings\n  const range = moment.range(<any>dateRange[0], <any>dateRange[1]);\n\n  return TIME_SERIES[granularity](range, options.timestampPrecision);\n};\n\nexport const isPredefinedGranularity = (granularity: string): boolean => !!TIME_SERIES[granularity];\n\nexport const FROM_PARTITION_RANGE = '__FROM_PARTITION_RANGE';\n\nexport const TO_PARTITION_RANGE = '__TO_PARTITION_RANGE';\n\nexport const BUILD_RANGE_START_LOCAL = '__BUILD_RANGE_START_LOCAL';\n","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-backend-shared/src/time.ts#L228-L264","documentation":"timeSeries() requires options.timestampPrecision to be set (truthy); the default parameter only applies when options is omitted entirely, so passing an explicit options object without timestampPrecision (or with 0/undefined) triggers this throw. The precision controls the millisecond precision of generated range timestamps and must be explicitly confirmed.","triggerScenarios":"timeSeries('day', range, {}) or timeSeries('day', range, { timestampPrecision: undefined }) — any call supplying an options object lacking a truthy timestampPrecision.","commonSituations":"Spreading partial config objects ({...userOptions}) into options; building options conditionally where timestampPrecision is dropped; TypeScript callers relying on the default but then passing an empty object literal.","solutions":["Pass { timestampPrecision: 3 } (or the precision you need) in the options object.","Omit the options argument entirely so the default { timestampPrecision: 3 } applies.","Merge defaults before calling: options = { timestampPrecision: 3, ...partialOptions }."],"exampleFix":"// before\ntimeSeries('day', range, {}); // throws: timestampPrecision is required\n\n// after\ntimeSeries('day', range, { timestampPrecision: 3 });","handlingStrategy":"validation","validationCode":"function buildTimeSeriesOptions(o: Partial<{ timestampPrecision: number }> = {}) {\n  const opts = { timestampPrecision: 3, ...o };\n  if (!opts.timestampPrecision) throw new Error('timestampPrecision must be set (e.g. 3 for milliseconds)');\n  return opts;\n}","typeGuard":"function hasTimestampPrecision(o: unknown): o is { timestampPrecision: number } {\n  return typeof o === 'object' && o !== null && typeof (o as any).timestampPrecision === 'number' && (o as any).timestampPrecision > 0;\n}","tryCatchPattern":"try {\n  return timeSeries(g, range, userOptions);\n} catch (e) {\n  if (/timestampPrecision is required/.test(String(e))) {\n    return timeSeries(g, range, { ...userOptions, timestampPrecision: 3 });\n  }\n  throw e;\n}","preventionTips":["Always spread defaults: { timestampPrecision: 3, ...partial }","Don't pass empty object literals for options","Type the options param in your wrappers so TS enforces the field","Watch for falsy precisions (0) which also trigger the throw"],"tags":["time-series","options","validation","typescript"],"backgroundTag":"missing-required-option","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}