{"record":{"id":"c38367fdb8a69a0e","repo":"fabricjs/fabric.js","slug":"no-class-registered-for-classtype","errorCode":null,"errorMessage":"No class registered for ${classType}","messagePattern":"No class registered for (.+?)","errorType":"exception","errorClass":"FabricError","httpStatus":null,"severity":"error","filePath":"packages/core/src/ClassRegistry.ts","lineNumber":34,"sourceCode":"export const SVG = 'svg';\n\nexport class ClassRegistry {\n  declare [JSON]: Map<string, any>;\n  declare [SVG]: Map<string, any>;\n\n  constructor() {\n    this[JSON] = new Map();\n    this[SVG] = new Map();\n  }\n\n  has(classType: string): boolean {\n    return this[JSON].has(classType);\n  }\n\n  getClass<T>(classType: string): T {\n    const constructor = this[JSON].get(classType);\n    if (!constructor) {\n      throw new FabricError(`No class registered for ${classType}`);\n    }\n    return constructor;\n  }\n\n  setClass(classConstructor: any, classType?: string) {\n    if (classType) {\n      this[JSON].set(classType, classConstructor);\n    } else {\n      this[JSON].set(classConstructor.type, classConstructor);\n      // legacy\n      // @TODO: needs to be removed in fabric 7 or 8\n      this[JSON].set(classConstructor.type.toLowerCase(), classConstructor);\n    }\n  }\n\n  getSVGClass(SVGTagName: string): any {\n    return this[SVG].get(SVGTagName);\n  }","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/fabricjs/fabric.js/blob/2bd4992cabf4ec9609aa349ea09b723cadc94bef/packages/core/src/ClassRegistry.ts#L16-L52","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst json = '{\"objects\":[{\"type\":\"textbox\",\"text\":\"hi\"}]}';\ncanvas.loadFromJSON(json); // throws: No class registered for textbox\n\n// after\nimport { Textbox } from 'fabric'; // or the module that registers it\nconst json = '{\"objects\":[{\"type\":\"textbox\",\"text\":\"hi\"}]}';\ncanvas.loadFromJSON(json);","handlingStrategy":"validation","validationCode":"import { classRegistry } from 'fabric';\nconst type = obj.type;\nif (!classRegistry.getClass(type)) {\n  console.warn(`Unknown type \"${type}\" in JSON; skipping or substituting.`);\n} else {\n  const Klass = classRegistry.getClass(type);\n}","typeGuard":"const isRegisteredType = (t: unknown): t is string =>\n  typeof t === 'string' && classRegistry.getClass(t) !== undefined;","tryCatchPattern":"try {\n  await canvas.loadFromJSON(json);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('No class registered for')) {\n    // import/register the missing class, or filter unknown objects out of the JSON and retry\n  } else throw e;\n}","preventionTips":["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."],"tags":["fabricjs","class-registry","deserialization","json","custom-class"],"backgroundTag":"unknown-type-deserialization","analyzedSha":"2bd4992cabf4ec9609aa349ea09b723cadc94bef","analyzedAt":"2026-08-28T10:56:44.286Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}