octobercms/october · error · ApplicationException
cms::lang.cms_object.error_saving
Error message
cms::lang.cms_object.error_saving
What it means
ApplicationException thrown by `Lang::save()` when `File::put($fullPath, $content)` returns false — the language file could not be written even though its directory exists. Typical causes: no write permission on the file or directory, a full disk, or an OS-level denial (SELinux, read-only mount).
Source
Thrown at modules/cms/classes/Lang.php:275
throw new ApplicationException(LangHelper::get(
'cms::lang.cms_object.file_already_exists',
['name'=>$this->fileName]
));
}
$dirPath = $this->theme->getPath().'/'.$this->dirName;
if (!file_exists($dirPath) || !is_dir($dirPath)) {
if (!File::makeDirectory($dirPath, 0755, true, true)) {
throw new ApplicationException(LangHelper::get(
'cms::lang.cms_object.error_creating_directory',
['name'=>$dirPath]
));
}
}
$newFullPath = $fullPath;
if (@File::put($fullPath, $this->content) === false) {
throw new ApplicationException(LangHelper::get(
'cms::lang.cms_object.error_saving',
['name'=>$this->fileName]
));
}
if (strlen($this->originalFileName) && $this->originalFileName !== $this->fileName) {
$fullPath = $this->getFilePath($this->originalFileName);
if (File::isFile($fullPath)) {
@unlink($fullPath);
}
}
clearstatcache();
$this->mtime = @File::lastModified($newFullPath);
$this->originalFileName = $this->fileName;
$this->exists = true;View on GitHub (pinned to b608633a7e)
Solutions
- Fix ownership/permissions on the existing file and its directory: `chown www-data: file dir` and ensure writable bits.
- Check free disk space (`df -h`) and clear space if full.
- Audit SELinux/apparmor denials and mount flags if permissions look correct but writes still fail.
Example fix
# before — file owned by root, web server cannot write $ ls -l themes/mytheme/lang/en.json -rw-r--r-- root root themes/mytheme/lang/en.json # after sudo chown www-data:www-data themes/mytheme/lang/en.json sudo chmod u+w themes/mytheme/lang/en.json
Defensive patterns
Strategy: validation
Validate before calling
$path = $lang->getFilePath();
if (file_exists($path) && !is_writable($path)) {
return back()->with('error', 'The file exists but is not writable by the web server.');
}
if (!is_writable(dirname($path))) {
return back()->with('error', 'The lang directory is not writable.');
}
$lang->save(); Try / catch
try {
$lang->save();
} catch (ApplicationException $e) {
// error_saving: log the resolved path + disk_free_space for ops triage
Log::error('Lang save failed', ['path' => $lang->getFilePath(), 'disk_free' => @disk_free_space(dirname($lang->getFilePath()))]);
throw $e;
} Prevention
- Monitor disk space; a full disk is a common cause of File::put returning false.
- Avoid creating theme files as root on CLI — the web server then can't overwrite them.
- Include is_writable() assertions in your deployment smoke tests.
When it happens
Trigger: Saving a lang file when `themes/<theme>/lang/xx.json` exists but is owned by another user (e.g. created via root CLI); disk full; read-only NFS/container mount; safe_mode/open_basedir blocking writes.
Common situations: Files created by CLI (root) then edited through the web backend; CI containers with ephemeral read-only layers; disks that filled up with logs; SELinux httpd_t write denials.
Related errors
- cms::lang.cms_object.error_creating_directory
- cms::lang.lang.error_deleting_file
- editor::lang.filesystem.error_renaming
- editor::lang.filesystem.error_deleting_file
- editor::lang.filesystem.error_deleting_dir
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/1c6dcd59499d5285.
Report an issue: GitHub.