mjmlio/mjml · error · Error
Specified filePath does not exist
Error message
Specified filePath does not exist
What it means
mjml-cli's fileContext helper resolves the directory containing an input file by lstat-ing the given filePath. If the path cannot be stat-ed at all (fs.lstatSync throws ENOENT), the helper re-throw a clearer Error('Specified filePath does not exist') instead of leaking the raw ENOENT. It is a guard against running mjml CLI commands on a file or directory path that is not on disk.
Source
Thrown at packages/mjml-cli/src/helpers/fileContext.js:23
/<mj-include[^<>]+path=['"](.*(?:\.mjml|\.css|\.html))['"]\s*[^<>]*(\/>|>\s*<\/mj-include>)/gi
const ensureIncludeIsSupportedFile = (file) =>
path.extname(file).match(/\.mjml|\.css|\.html/) ? file : `${file}.mjml`
const error = (e) => console.error(e.stack || e) // eslint-disable-line no-console
export default (baseFile, filePath) => {
const filesIncluded = []
let filePathDirectory = ''
if (filePath) {
try {
const isFilePathDir = fs.lstatSync(filePath).isDirectory()
filePathDirectory = isFilePathDir ? filePath : path.dirname(filePath)
} catch (e) {
if (e.code === 'ENOENT') {
throw new Error('Specified filePath does not exist')
} else {
throw e
}
}
}
const readIncludes = (dir, file, base) => {
const currentFile = path.resolve(
dir
? path.join(dir, ensureIncludeIsSupportedFile(file))
: ensureIncludeIsSupportedFile(file),
)
const currentDirectory = path.dirname(currentFile)
const includes = new RegExp(includeRegexp)
let contentView on GitHub (pinned to 6c01d35af5)
Solutions
- Verify the path exists with ls/test -f before invoking mjml and correct typos.
- Run the command from the directory containing the file, or pass an absolute path.
- If the file is build-generated, ensure the preceding build step ran and produced it.
- Wrap the mjml invocation in a check like fs.existsSync(filePath) in scripts.
Example fix
// before mjml ./template.mjml -o ./out.html // ENOENT: template.mjml missing // after ls ./template.mjml # confirm it exists / fix the path mjml ./templates/newsletter.mjml -o ./out.html
Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
if (!fs.existsSync(filePath)) throw new Error(`Input not found: ${filePath}`); Try / catch
try {
runMjmlCli(args)
} catch (e) {
if (e.message === 'Specified filePath does not exist') {
console.error(`Path not found: ${args[0]}. cwd=${process.cwd()}`)
process.exit(1)
}
throw e
} Prevention
- Use absolute paths in scripts and CI configs.
- Check file existence in build steps before invoking the CLI.
- Keep watch/glob configs in sync with actual file locations.
When it happens
Trigger: Running a CLI command that resolves a file context (e.g. mjml --watch or compile helpers) with an input/output path that does not exist; passing a relative path from a different working directory; a glob or config pointing at a deleted/moved file.
Common situations: Typo in the mjml file name on the command line; running mjml before the input file is generated by a build step; a watch configuration referencing a file that was renamed or deleted; wrong cwd when using relative paths in scripts or CI.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Specified filePath does not exist
- e.formattedMessage (compiled MJML errors printed via console
- [MJML] Some mj-include paths were denied because they are ou
- [MJML] mj-include tags were found but includes are disabled
- Cannot read file: ${path} doesn't exist or no access
AI-assisted analysis of mjmlio/mjml@6c01d35af5 (2026-09-02).
Data as JSON: /api/errors/b5e51850de508515.
Report an issue: GitHub.