mjmlio/mjml · warning
[MJML] mj-include tags were found but includes are disabled…
Error message
[MJML] mj-include tags were found but includes are disabled by default.\n Files: ${filesWithIgnoredIncludes.join(', ')}\n To enable includes, add --config.allowIncludes true to your command.\n See https://documentation.mjml.io/#mj-include for security notes. What it means
By default MJML disables mj-include processing for security reasons. When the CLI detects <mj-include> tags in the source input but includes were not enabled, it warns that those tags were ignored (left unprocessed) and output will not contain the included content.
Solutions
- Add --config.allowIncludes true to the mjml command to enable includes
- Then configure --config.includePath with the directories that may be included (see the related denied-includes warning)
- Or remove/replace the <mj-include> tags if includes are not wanted
- Pin/lock team build scripts so the flag is not lost when commands are copied
Example fix
// before mjml email.mjml // after mjml email.mjml --config.allowIncludes true --config.includePath ./partials
Defensive patterns
Strategy: validation
Validate before calling
const src = fs.readFileSync(input, 'utf8')
if (/<mj-include\b/i.test(src) && !allowIncludes) {
throw new Error('Input uses <mj-include>; run with --config.allowIncludes true')
} Type guard
const usesIncludes = (mjml) => typeof mjml === 'string' && /<mj-include\b/i.test(mjml)
Prevention
- Add --config.allowIncludes true wherever templates use mj-include
- Pre-scan inputs with /<mj-include\b/i before building
- Standardize the CLI invocation in a shared build script
- Note the flag in template-authoring guidelines
When it happens
Trigger: Running the mjml CLI on a file whose source matches /<mj-include\b/i without passing --config.allowIncludes true. No includePath check even runs; the includes are simply skipped.
Common situations: Upgrading MJML from a version where includes were on by default; copying templates that use mj-include into a build that never opted in; new team members unaware of the allowIncludes flag.
Related errors
- [MJML] Some mj-include paths were denied because they are…
- [MJML security] includePath
- An mj-head element add an unkown head attribute
- "dependencies" must be an object.
- "dependencies" option should be provided to mjml validator
AI-assisted analysis of mjmlio/mjml@6c01d35af5 (2026-09-02).
Data as JSON: /api/errors/9c1f51ddad4e3b45.
Report an issue: GitHub.
Appendix: source
Thrown at packages/mjml-cli/src/client.js:350
// eslint-disable-next-line no-console
console.warn(
`[MJML] Some mj-include paths were denied because they are outside the allowed directories.\n` +
` Files: ${filesWithDeniedIncludes.join(', ')}\n` +
` Add the include directories to --config.includePath to allow them.\n` +
` See https://documentation.mjml.io/#mj-include for security notes.`,
)
}
}
// Warn when mj-include tags are present but includes are still ignored.
if (config.ignoreIncludes !== false) {
const MJ_INCLUDE_RE = /<mj-include\b/i
const filesWithIgnoredIncludes = inputs
.filter((i) => i && i.mjml && MJ_INCLUDE_RE.test(i.mjml))
.map((i) => i.file)
if (filesWithIgnoredIncludes.length) {
// eslint-disable-next-line no-console
console.warn(
`[MJML] mj-include tags were found but includes are disabled by default.\n` +
` Files: ${filesWithIgnoredIncludes.join(', ')}\n` +
` To enable includes, add --config.allowIncludes true to your command.\n` +
` See https://documentation.mjml.io/#mj-include for security notes.`,
)
}
}
failedStream.forEach(({ error, file }) => {
console.error(`${file ? `File: ${file}\n` : null}${error}`) // eslint-disable-line no-console
if (config.stack) {
console.error(error.stack) // eslint-disable-line no-console
}
})
if (inputOpt === 'v') {
const isInvalid =View on GitHub (pinned to 6c01d35af5)