chartjs/Chart.js · critical · Error
This method is not implemented: Check that a complete date a
Error message
This method is not implemented: Check that a complete date adapter is provided.
What it means
Chart.js ships its base DateAdapter (DateAdapterBase) with every method (formats, parse, format, add, diff, startOf, endOf) implemented as a stub that calls the internal abstract() helper, which throws this error. The time scale depends on these methods to parse data, generate ticks, and format labels. The library throws it because Chart.js core deliberately does NOT bundle a date library; a concrete adapter (e.g. chartjs-adapter-date-fns, chartjs-adapter-luxon, chartjs-adapter-moment) must be registered separately to supply real implementations.
Source
Thrown at src/core/core.adapters.ts:66
diff(this: DateAdapter<T>, a: number, b: number, unit: TimeUnit): number;
/**
* Returns start of `unit` for the given `timestamp`.
* @param timestamp - the input timestamp
* @param unit - the unit as string
* @param [weekday] - the ISO day of the week with 1 being Monday
* and 7 being Sunday (only needed if param *unit* is `isoWeek`).
*/
startOf(this: DateAdapter<T>, timestamp: number, unit: TimeUnit | 'isoWeek', weekday?: number | boolean): number;
/**
* Returns end of `unit` for the given `timestamp`.
* @param timestamp - the input timestamp
* @param unit - the unit as string
*/
endOf(this: DateAdapter<T>, timestamp: number, unit: TimeUnit): number;
}
function abstract<T = void>(): T {
throw new Error('This method is not implemented: Check that a complete date adapter is provided.');
}
/**
* Date adapter (current used by the time scale)
* @namespace Chart._adapters._date
* @memberof Chart._adapters
* @private
*/
class DateAdapterBase implements DateAdapter {
/**
* Override default date adapter methods.
* Accepts type parameter to define options type.
* @example
* Chart._adapters._date.override<{myAdapterOption: string}>({
* init() {
* console.log(this.options.myAdapterOption);
* }View on GitHub (pinned to cb02e1d207)
Solutions
- Install and import a date adapter: `npm i chartjs-adapter-date-fns` then `import 'chartjs-adapter-date-fns';` (or luxon/moment) BEFORE creating the chart.
- If using the auto bundle, import from 'chart.js/auto' which registers scales but still requires the adapter side-effect import separately.
- For a custom adapter, override ALL seven methods (formats, parse, format, add, diff, startOf, endOf) via Chart._adapters._date.override({...}) or by extending DateAdapterBase.
- Verify the adapter import is not tree-shaken: place it as a top-level import with side effects, not a dynamic import that may be dropped.
Example fix
// before
import { Chart } from 'chart.js';
new Chart(ctx, { type: 'line', data, options: { scales: { x: { type: 'time' } } } });
// after
import { Chart } from 'chart.js';
import 'chartjs-adapter-date-fns'; // registers concrete DateAdapter methods
new Chart(ctx, { type: 'line', data, options: { scales: { x: { type: 'time' } } } }); Defensive patterns
Strategy: validation
Validate before calling
// Detect a missing/incomplete date adapter before creating a time scale.
import { Chart, _adapters } from 'chart.js';
function hasDateAdapter() {
const a = new Chart._adapters._date();
// abstract methods throw 'This method is not implemented' when not overridden
try {
a.parse(Date.now());
a.format(Date.now(), 'yyyy');
a.add(0, 1, 'day');
return true;
} catch (e) {
return /not implemented/.test(String(e.message));
}
}
if (!hasDateAdapter()) {
throw new Error('Import a date adapter (e.g. chartjs-adapter-date-fns) before using time scales.');
} Type guard
// Type-level guard ensuring the time scale is only used with a registered adapter.
import type { ChartOptions } from 'chart.js';
function assertTimeScaleReady<T extends ChartOptions>(opts: T): T {
const scales = (opts.scales ?? {}) as Record<string, any>;
for (const [id, s] of Object.entries(scales)) {
if (s?.type === 'time' || s?.type === 'timeseries') {
// runtime reminder; real check is the adapter import above
if (!('chartjs-adapter-date-fns' in globalThis)) {
console.warn(`Scale '${id}' is type '${s.type}'; ensure a date adapter is imported.`);
}
}
}
return opts;
} Prevention
- Always import the date adapter as a top-level side-effect import in the same entry that imports 'chart.js'.
- Add a smoke test that constructs a tiny time-scale chart to fail builds that drop the adapter.
- Document the adapter dependency in onboarding docs for any team using time scales.
- Beware tree-shaking: if you import from 'chart.js' (not '/auto'), the adapter must still be imported separately.
When it happens
Trigger: Loading a time scale (type: 'time' or 'timeseries') without importing/registering a date adapter; importing the bare 'chart.js' entry instead of the 'chart.js/auto' auto-register bundle; or registering an adapter that does not override one of the seven DateAdapter methods (partial override). The throw happens the first time the time scale calls the adapter (during data parsing or tick generation in TimeScale._generate / _parse).
Common situations: Upgrading from Chart.js 3 (where date-fns adapter was sometimes pulled in transitively) to v4 and forgetting the adapter; using tree-shaking/bundler setups that drop the adapter side-effect import; mixing 'chart.js/auto' with a manual adapter import that gets elided; or writing a custom adapter and forgetting to implement one method (e.g. startOf) via Chart._adapters._date.override({...}).
Related errors
- "${id}" is not a registered ${type}.
- ${min} and ${max} are too far apart with stepSize of ${stepS
- Cannot determine type of '${id}' axis. Please provide 'axis'
- class does not have id: ${item}
- Recursion detected: ${Array.from(_stack).join('->')}->${prop
AI-assisted analysis of chartjs/Chart.js@cb02e1d207 (2026-08-12).
Data as JSON: /api/errors/34c210b2c643f303.
Report an issue: GitHub.