octobercms/october · error · ValidationException
cms::lang.cms_object.invalid_file
Error message
cms::lang.cms_object.invalid_file
What it means
ValidationException thrown while loading a theme language file: the requested file name resolved to a path that fails `FileHelper::validateInTheme()`, i.e. the path does not stay inside the theme directory. Theme lang files live in `themes/<theme>/lang/` and must be plain .json base names; any `../` traversal, absolute path, or otherwise escaping path is rejected before the file is read.
Source
Thrown at modules/cms/classes/Lang.php:209
$foundTheme = $this->theme;
if (!File::isFile($filePath)) {
// Look at parent
if ($parentTheme = $this->theme->getParentTheme()) {
$foundTheme = $parentTheme;
$filePath = $parentTheme->getPath().'/'.$this->dirName.'/'.$fileName;
if (!File::isFile($filePath)) {
return null;
}
}
else {
return null;
}
}
if (!FileHelper::validateInTheme($foundTheme, $filePath)) {
throw new ValidationException(['fileName' =>
LangHelper::get('cms::lang.cms_object.invalid_file', [
'name' => $fileName
])
]);
}
if (($content = @File::get($filePath)) === false) {
return null;
}
$this->fileName = $fileName;
$this->originalFileName = $fileName;
$this->mtime = File::lastModified($filePath);
$this->content = $content;
$this->exists = true;
return $this;
}View on GitHub (pinned to b608633a7e)
Solutions
- Pass only a plain base file name (e.g. 'en.json') — never directories, absolute paths, or traversal sequences.
- Sanitize incoming file names with `basename()` plus an allow-list regex before handing them to the Lang API.
- If you legitimately need nested lang files, use the theme's own directory structure support, not path strings in fileName.
Example fix
// before $file = Lang::load($theme, '../config/secrets.json'); // after — base name only, must live inside themes/<theme>/lang/ $file = Lang::load($theme, 'en.json');
Defensive patterns
Strategy: validation
Validate before calling
$fileName = $request->input('fileName');
if (!is_string($fileName) || !preg_match('/^[\w\-\.]+\.json$/i', $fileName)) {
throw new ValidationException(['fileName' => 'Invalid file name']);
}
// basename() as belt-and-braces, then load
$lang = Lang::load($theme, basename($fileName)); Try / catch
try {
$lang = Lang::load($theme, $fileName);
} catch (Winter\Storm\Exception\ValidationException $e) {
// invalid_file means the name escaped the theme: reject, never retry raw input
return back()->withErrors($e->getErrors());
} Prevention
- Treat any file name containing '/', '\\', or '..' as hostile at the request boundary.
- Whitelist with a regex (base name + allowed extension) before touching CMS file APIs.
- Wrap file-management endpoints in validation middleware so traversal attempts are logged.
When it happens
Trigger: Loading a lang object with a file name containing '../' (e.g. '../../config/app.json'), a leading slash / absolute path, or any segment that resolves outside the theme root; a crafted `fileName` parameter sent to a lang-file management endpoint.
Common situations: Path-traversal attempts against theme file APIs; an API client or import script passing OS-style paths instead of base file names; code reused from a different file API that assumed subdirectory support.
Related errors
- cms::lang.cms_object.invalid_property
- cms::lang.cms_object.file_name_required
- cms::lang.cms_object.invalid_file_extension
- File not found
- editor::lang.filesystem.error_deleting_directory
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/24a28b86ffa4a66b.
Report an issue: GitHub.