{"record":{"id":"32a9272ff02db5b5","repo":"mjmlio/mjml","slug":"validationerror-n-errors-map-e-e-formatte","errorCode":null,"errorMessage":"ValidationError: \\n ${errors.map((e) => e.formattedMessage).join('\\n')}","messagePattern":"ValidationError: \\\\n (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"packages/mjml-core/src/index.js","lineNumber":650,"sourceCode":"    lang: get(mjml, 'attributes.lang') || 'und',\n    dir: get(mjml, 'attributes.dir') || 'auto',\n  }\n\n  const validatorOptions = {\n    components,\n    dependencies,\n    initializeType,\n  }\n\n  switch (validationLevel) {\n    case 'skip':\n      break\n\n    case 'strict':\n      errors = MJMLValidator(mjml, validatorOptions)\n\n      if (errors.length > 0) {\n        throw new ValidationError(\n          `ValidationError: \\n ${errors\n            .map((e) => e.formattedMessage)\n            .join('\\n')}`,\n          errors,\n        )\n      }\n      break\n\n    case 'soft':\n    default:\n      errors = MJMLValidator(mjml, validatorOptions)\n      break\n  }\n\n  const mjBody = find(mjml.children, { tagName: 'mj-body' })\n  const mjHead = find(mjml.children, { tagName: 'mj-head' })\n  const mjOutsideRaws = filter(mjml.children, { tagName: 'mj-raw' })\n","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/mjmlio/mjml/blob/6c01d35af5da14108b86bbf052232e99de7ca755/packages/mjml-core/src/index.js#L632-L668","documentation":"In strict validation mode, mjml2html runs MJMLValidator over the parsed document and, if any validation errors are found, throws a ValidationError whose message lists each error's formattedMessage. Unlike loose/skip modes which collect warnings, strict mode fails fast so invalid MJML never renders.","triggerScenarios":"Calling mjml2html with validationLevel: 'strict' on a document containing any validation error, e.g. unknown component tags like <mj-foo>, invalid attribute values, or components in forbidden parents.","commonSituations":"CI pipelines configured with strict validation that newly introduced an unsupported component or attribute typo; upgrading mjml where a component/attribute was deprecated; custom components registered under a name the validator does not know.","solutions":["Fix each listed formattedMessage: correct the tag name, attribute, or structure at the given line in your MJML.","Register custom components with the validator so unknown-tag errors disappear (registerMJElement/component registration).","Set validationLevel to 'soft' (warn only) or 'skip' if you intentionally render non-strict documents.","Compare against MJML docs for deprecated components after a version upgrade."],"exampleFix":"// before\nmjml2html(mjml, { validationLevel: 'strict' }) // <mj-foo> unknown\n// after\nmjml2html(mjml.replace('<mj-foo>', '<mj-text>'), { validationLevel: 'strict' })\n// or: { validationLevel: 'soft' } to downgrade to warnings","handlingStrategy":"try-catch","validationCode":"import { MJMLValidator } from 'mjml-validator'\nconst errs = MJMLValidator(require('mjml-parser-xml')(mjmlString))\nif (errs.length) console.warn('MJML validation issues:', errs.map(e => e.formattedMessage))","typeGuard":null,"tryCatchPattern":"import { ValidationError } from 'mjml-core'\ntry {\n  return mjml2html(src, { validationLevel: 'strict' })\n} catch (e) {\n  if (e instanceof ValidationError) {\n    console.error('MJML validation failed:', e.errors.map(x => x.formattedMessage).join('\\n'))\n  } else throw e\n}","preventionTips":["Run validation as a pre-commit/CI step on all templates.","Register custom components before validating/rendering.","Pin mjml versions and re-validate templates after upgrades."],"tags":["validation","strict-mode","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"6c01d35af5da14108b86bbf052232e99de7ca755","analyzedAt":"2026-09-02T21:31:03.649Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}