{"record":{"id":"6d7c0f015093ae6d","repo":"mjmlio/mjml","slug":"no-type-found-for-typeconfig","errorCode":null,"errorMessage":"No type found for ${typeConfig}","messagePattern":"No type found for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mjml-core/src/types/type.js","lineNumber":16,"sourceCode":"import { some, find } from 'lodash'\nimport typesConstructors from './index'\n\n// Avoid recreate existing types\nexport const types = {}\n\nexport const initializeType = (typeConfig) => {\n  if (types[typeConfig]) {\n    return types[typeConfig]\n  }\n\n  const { typeConstructor } =\n    find(typesConstructors, (type) => !!typeConfig.match(type.matcher)) || {}\n\n  if (!typeConstructor) {\n    throw new Error(`No type found for ${typeConfig}`)\n  }\n\n  types[typeConfig] = typeConstructor(typeConfig)\n\n  return types[typeConfig]\n}\n\nexport default class Type {\n  constructor(value) {\n    this.value = value\n  }\n\n  isValid() {\n    return some(this.matchers, (matcher) => `${this.value}`.match(matcher))\n  }\n\n  getErrorMessage() {\n    if (this.isValid()) {","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/mjmlio/mjml/blob/6c01d35af5da14108b86bbf052232e99de7ca755/packages/mjml-core/src/types/type.js#L1-L34","documentation":"initializeType resolves a type config string (e.g. used by mjml attribute validators) against a list of known type constructors by matching each type's matcher regex. When no registered constructor's matcher matches the given typeConfig string, it throws 'No type found for <typeConfig>'. This means the requested type name is not part of mjml-core's built-in type registry.","triggerScenarios":"Declaring an attribute type in a custom element definition (e.g. type: 'colorr' or an unsupported type like 'email') that no registered matcher accepts, which then flows into initializeType when the element's types are initialized.","commonSituations":"Typo in a custom component's attribute type; copying a type name from another validation library (e.g. Joi/Zod style names); core upgrade or downgrade where a type was removed or renamed; building custom elements with an unregistered custom type.","solutions":["Check the message's typeConfig value and fix the typo / use a supported type (string, color, unit, enum, etc.).","If you need a custom type, register a matching type constructor in the types registry before initializing elements.","Grep your component definitions for the offending type string and correct all occurrences.","Verify against the mjml-core version in use that the type still exists."],"exampleFix":"// before\nattributes: { color: { type: 'colour' } }\n// after\nattributes: { color: { type: 'color' } }","handlingStrategy":"type-guard","validationCode":"const SUPPORTED = ['string', 'color', 'unit', 'enum', 'boolean', 'number'];\nfunction checkAttrTypes(componentDef) {\n  for (const [name, a] of Object.entries(componentDef.attributes || {})) {\n    if (a.type && !SUPPORTED.includes(a.type)) throw new Error(`Unsupported attribute type '${a.type}' on ${name}`);\n  }\n}","typeGuard":"function hasKnownType(attr) {\n  return typeof attr === 'object' && attr != null && typeof attr.type === 'string' &&\n    ['string', 'color', 'unit', 'enum', 'boolean', 'number'].includes(attr.type);\n}","tryCatchPattern":"try {\n  registerComponent(MyElement)\n} catch (e) {\n  if (e.message.startsWith('No type found for')) {\n    console.error(`Fix attribute type in element definition: ${e.message}`)\n  } else throw e\n}","preventionTips":["Copy type names from official mjml docs, not from memory.","Type-check custom element definitions against the core types list.","Re-check custom types after mjml-core upgrades."],"tags":["types","validation","configuration","custom-components"],"backgroundTag":"unknown-type-name","analyzedSha":"6c01d35af5da14108b86bbf052232e99de7ca755","analyzedAt":"2026-09-02T21:31:03.649Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}