cube-js/cube · error · Error

Date bin function, required for custom time dimension granul

Error message

Date bin function, required for custom time dimension granularities, is not implemented for this data source

What it means

dateBin(interval, source, origin) implements the SQL needed to bin timestamps into custom-granularity intervals aligned to an origin (like Postgres 14's date_bin). BaseQuery's default throws because each DB has different syntax and many have no equivalent. It is only needed when using custom granularities (arbitrary intervals beyond standard day/week/month).

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/BaseQuery.js:4158

   * @param {string} dimension
   * @return {string}
   */
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  timeGroupedColumn(granularity, dimension) {
    throw new Error('Not implemented');
  }

  /**
   * Returns sql for source expression floored to timestamps aligned with
   * intervals relative to origin timestamp point
   * @param {string} interval (a value expression of type interval)
   * @param {string} source (a value expression of type timestamp/date)
   * @param {string} origin (a value expression of type timestamp/date without timezone)
   * @returns {string}
   */
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  dateBin(interval, source, origin) {
    throw new Error('Date bin function, required for custom time dimension granularities, is not implemented for this data source');
    // Different syntax possible in different DBs
  }

  /**
   * Returns the lowest time unit for the interval
   * @protected
   * @param {string} interval
   * @returns {string}
   */
  diffTimeUnitForInterval(interval) {
    if (/second/i.test(interval)) {
      return 'second';
    } else if (/minute/i.test(interval)) {
      return 'minute';
    } else if (/hour/i.test(interval)) {
      return 'hour';
    } else if (/day/i.test(interval)) {
      return 'day';

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Implement dateBin in your adapter (e.g. emulate with epoch math: floor((ts - origin)/interval)*interval + origin)
  2. Restrict the query to standard granularities supported natively by the DB
  3. Upgrade to a data source with native date_bin/binning support

Example fix

// before
class MyQuery extends BaseQuery {} // custom granularity on query
// after
class MyQuery extends BaseQuery {
  dateBin(interval, source, origin) {
    return `to_timestamp(floor(extract(epoch from ${source} - ${origin}) / extract(epoch from ${interval})) * extract(epoch from ${interval}) + extract(epoch from ${origin}))`;
  }
}
Defensive patterns

Strategy: fallback

Validate before calling

const standardGranularities = ['second','minute','hour','day','week','month','quarter','year'];
if (query.timeDimensions?.some(td => td.granularity && !standardGranularities.includes(td.granularity)) &&
    !adapterImplementsDateBin(dataSource)) {
  throw new Error(`Custom granularities unsupported on ${dataSource}; use a standard granularity`);
}

Type guard

function supportsDateBin(adapter) {
  return typeof adapter.dateBin === 'function' &&
    adapter.dateBin !== BaseQuery.prototype.dateBin;
}

Try / catch

try { return await cube.load(query); } catch (e) {
  if (/Date bin function/.test(e.message)) {
    return await cube.load({ ...query, timeDimensions: query.timeDimensions.map(td => ({ ...td, granularity: 'day' })) });
  }
  throw e;
}

Prevention

When it happens

Trigger: A query uses a custom granularity (e.g. interval like '15 minutes' or non-standard offsets) on a data source whose adapter did not implement dateBin.

Common situations: Custom rolling granularities on MySQL/MSSQL/older Postgres without date_bin; migrating queries with custom granularities from Postgres to another DB.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/b4fed0dd6a47cd67. Report an issue: GitHub.