apache/echarts · error · Error
Component {mainType}.{subType} is used but not imported.
Error message
Component {mainType}.{subType} is used but not imported. What it means
Thrown by the same `getClass(mainType, subType, throwWhenNotFound)` in clazz.ts:289, but on the `subType` branch: a specific component subtype was requested (e.g. `series.graph`, `visualMap.piecewise`), the main type's subclass container existed, yet no class was registered under that sub-key. The message 'Component X.Y is used but not imported.' is ECharts' canonical signal that the chart/component subtype referenced in the option was never registered. Like error 41, this throw is not gated by `__DEV__` and can fire in production.
Source
Thrown at src/util/clazz.ts:289
container[componentTypeInfo.sub] = clz;
}
}
return clz;
};
target.getClass = function (
mainType: ComponentMainType,
subType?: ComponentSubType,
throwWhenNotFound?: boolean
): Constructor {
let clz = storage[mainType];
if (clz && (clz as SubclassContainer)[IS_CONTAINER]) {
clz = subType ? (clz as SubclassContainer)[subType] : null;
}
if (throwWhenNotFound && !clz) {
throw new Error(
!subType
? mainType + '.' + 'type should be specified.'
: 'Component ' + mainType + '.' + (subType || '') + ' is used but not imported.'
);
}
return clz as Constructor;
};
target.getClassesByMainType = function (componentType: ComponentFullType): Constructor[] {
const componentTypeInfo = parseClassType(componentType);
const result: Constructor[] = [];
const obj = storage[componentTypeInfo.main];
if (obj && (obj as SubclassContainer)[IS_CONTAINER]) {
zrUtil.each(obj as SubclassContainer, function (o, type) {
type !== IS_CONTAINER && result.push(o as Constructor);View on GitHub (pinned to 30076aedcd)
Solutions
- Import and register the named chart/component before setOption: e.g. `import { GraphChart } from 'echarts/charts'; echarts.use([GraphChart]);` (use the subtype from the message).
- Cross-check every `type` value across `series` and component options against the entries in your `echarts.use([...])` array.
- Ensure registration runs before `chart.setOption(...)` and before any async option merge.
- For zero-config convenience (larger bundle), use the full bundle `import * as echarts from 'echarts';` which registers all built-in subtypes.
Example fix
// before
import * as echarts from 'echarts/core';
import { BarChart } from 'echarts/charts';
echarts.use([BarChart]); // 'Component series.graph is used but not imported.'
const option = { series: [{ type: 'graph', data: [...], links: [...] }] };
// after
import * as echarts from 'echarts/core';
import { BarChart, GraphChart } from 'echarts/charts';
echarts.use([BarChart, GraphChart]);
const option = { series: [{ type: 'graph', data: [...], links: [...] }] }; Defensive patterns
Strategy: validation
Validate before calling
// Collect every chart/component subtype used in the option and report any not
// present in your explicit registration allow-list.
function findUnregisteredSubtypes(option, registeredTypes) {
const used = new Set();
(option.series || []).forEach(s => s && s.type && used.add('series.' + s.type));
['visualMap', 'dataZoom', 'legend'].forEach(k =>
[].concat(option[k] || []).forEach(c => c && c.type && used.add(k + '.' + c.type)));
return [...used].filter(t => !registeredTypes.has(t));
}
// const missing = findUnregisteredSubtypes(option, new Set(['series.bar','series.line'])); Type guard
function isRegisteredSubtype(echartsRef, fullType) {
// echarts has no public hasClass; use a probe instance + try/catch as the guard.
const probe = echartsRef.init(document.createElement('div'));
const [main, sub] = fullType.split('.');
try {
probe.setOption(main === 'series' ? { series: [{ type: sub, data: [] }] } : { [main]: [{ type: sub }] });
return true;
} catch { return false; } finally { probe.dispose(); }
} Prevention
- Treat the `echarts.use([...])` array as a contract: any new `type` added to an option must be added there in the same change.
- Generate the registration list from a single source (e.g. a config array of supported chart/component types) so option validation and `.use()` cannot drift.
- In CI, run a parametric test that calls `setOption` for each supported subtype to catch missing imports before release.
When it happens
Trigger: The option contains `series: [{ type: 'graph' | 'line' | 'bar' | ... }]` (or a component with a subtype such as `visualMap: { type: 'piecewise' }`) while the matching submodule (GraphChart, LineChart, etc.) was omitted from `echarts.use([...])` in an on-demand build. `parseClassType` splits `series.graph` into main=`series`, sub=`graph`; the sub is absent from the container so getClass returns null and throws.
Common situations: The single most common ECharts on-demand mistake — forgetting one chart or component subtype in the `.use([...])` list; a dynamic/conditional option that includes a chart type registered only on some code paths; upgrading ECharts where a subtype was renamed or removed; a custom series whose model/view was never registered.
Related errors
- {mainType}.type should be specified.
- matrix coordinate system should be specified.
- Only one bmap component can exist
- Heatmap must use with visualMap
- levels[i].depth is mandatory and should be natural number
AI-assisted analysis of apache/echarts@30076aedcd (2026-08-12).
Data as JSON: /api/errors/cd57f0cda1a1e905.
Report an issue: GitHub.