fabricjs/fabric.js · error · FabricError
No class registered for ${classType}
Error message
No class registered for ${classType} What it means
Fabric.js keeps a registry (ClassRegistry) that maps string type names to class constructors, used when deserializing JSON (fromObject) and when resolving classes by string (getClass). When `getClass(classType)` is called with a name that was never registered via `setClass`, no constructor exists and this error is thrown. It typically means a class is not imported/registered before loading JSON that references it, or a custom class's `type` doesn't match the registered key.
Source
Thrown at packages/core/src/ClassRegistry.ts:34
export const SVG = 'svg';
export class ClassRegistry {
declare [JSON]: Map<string, any>;
declare [SVG]: Map<string, any>;
constructor() {
this[JSON] = new Map();
this[SVG] = new Map();
}
has(classType: string): boolean {
return this[JSON].has(classType);
}
getClass<T>(classType: string): T {
const constructor = this[JSON].get(classType);
if (!constructor) {
throw new FabricError(`No class registered for ${classType}`);
}
return constructor;
}
setClass(classConstructor: any, classType?: string) {
if (classType) {
this[JSON].set(classType, classConstructor);
} else {
this[JSON].set(classConstructor.type, classConstructor);
// legacy
// @TODO: needs to be removed in fabric 7 or 8
this[JSON].set(classConstructor.type.toLowerCase(), classConstructor);
}
}
getSVGClass(SVGTagName: string): any {
return this[SVG].get(SVGTagName);
}View on GitHub (pinned to 2bd4992cab)
Solutions
- Import the class (or its side-effectful registration module) before calling loadFromJSON/fromObject: e.g. `import { MyCustomClass } from './MyCustomClass'` and `ClassRegistry.setClass(MyCustomClass)` / `ClassRegistry.setClass(MyCustomClass, 'MyCustom')` when using a custom type string.
- Verify the `type` string in the JSON matches the registered key (custom `type` requires the second argument of setClass).
- Check the bundle: ensure side-effect imports aren't stripped (`sideEffects: true` in package config or explicit `import '...'` statements).
- If deserializing unknown types is expected, catch this error and skip or substitute a fallback object.
Example fix
// before
const json = '{"objects":[{"type":"textbox","text":"hi"}]}';
canvas.loadFromJSON(json); // throws: No class registered for textbox
// after
import { Textbox } from 'fabric'; // or the module that registers it
const json = '{"objects":[{"type":"textbox","text":"hi"}]}';
canvas.loadFromJSON(json); Defensive patterns
Strategy: validation
Validate before calling
import { classRegistry } from 'fabric';
const type = obj.type;
if (!classRegistry.getClass(type)) {
console.warn(`Unknown type "${type}" in JSON; skipping or substituting.`);
} else {
const Klass = classRegistry.getClass(type);
} Type guard
const isRegisteredType = (t: unknown): t is string => typeof t === 'string' && classRegistry.getClass(t) !== undefined;
Try / catch
try {
await canvas.loadFromJSON(json);
} catch (e) {
if (e instanceof Error && e.message.startsWith('No class registered for')) {
// import/register the missing class, or filter unknown objects out of the JSON and retry
} else throw e;
} Prevention
- Import and register every custom class before loadFromJSON/fromObject.
- Keep the `type` string in saved JSON in sync with the registered class name (use setClass(Klass, 'CustomType') for aliases).
- Mark registration modules as side-effectful so bundlers don't tree-shake them.
When it happens
Trigger: Calling `ClassRegistry.getClass('MyClass')` (directly or via `fabric.EnlivenObjects`/`loadFromJSON`) when 'MyClass' was never passed to `ClassRegistry.setClass`. Also happens with custom classes whose static `type` differs from the string stored in JSON, or when tree-shaking removes side-effectful registration imports.
Common situations: Loading a saved canvas JSON containing a custom object type without importing that class first; renaming a custom class or its `type` string between save and load; bundler (webpack/Vite production build) dropping registration side effects; using a plugin/filter that registers itself only via a side-effect import the user forgot to add.
Related errors
- Trying to initialize a canvas that has already been initiali
- Fabric env was not initialized. Import fabric, fabric/node,
- Vertex, fragment shader or program creation error
- Vertex shader compile error for ${this.type}: ${gl.getShader
- Fragment shader compile error for ${this.type}: ${gl.getShad
AI-assisted analysis of fabricjs/fabric.js@2bd4992cab (2026-08-28).
Data as JSON: /api/errors/c38367fdb8a69a0e.
Report an issue: GitHub.