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

  1. Fix ownership/permissions on the existing file and its directory: `chown www-data: file dir` and ensure writable bits.
  2. Check free disk space (`df -h`) and clear space if full.
  3. 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

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


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/1c6dcd59499d5285. Report an issue: GitHub.