{"record":{"id":"1c6dcd59499d5285","repo":"octobercms/october","slug":"cms-lang-cms-object-error-saving","errorCode":null,"errorMessage":"cms::lang.cms_object.error_saving","messagePattern":"cms::lang\\.cms_object\\.error_saving","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"modules/cms/classes/Lang.php","lineNumber":275,"sourceCode":"            throw new ApplicationException(LangHelper::get(\n                'cms::lang.cms_object.file_already_exists',\n                ['name'=>$this->fileName]\n            ));\n        }\n\n        $dirPath = $this->theme->getPath().'/'.$this->dirName;\n        if (!file_exists($dirPath) || !is_dir($dirPath)) {\n            if (!File::makeDirectory($dirPath, 0755, true, true)) {\n                throw new ApplicationException(LangHelper::get(\n                    'cms::lang.cms_object.error_creating_directory',\n                    ['name'=>$dirPath]\n                ));\n            }\n        }\n\n        $newFullPath = $fullPath;\n        if (@File::put($fullPath, $this->content) === false) {\n            throw new ApplicationException(LangHelper::get(\n                'cms::lang.cms_object.error_saving',\n                ['name'=>$this->fileName]\n            ));\n        }\n\n        if (strlen($this->originalFileName) && $this->originalFileName !== $this->fileName) {\n            $fullPath = $this->getFilePath($this->originalFileName);\n\n            if (File::isFile($fullPath)) {\n                @unlink($fullPath);\n            }\n        }\n\n        clearstatcache();\n\n        $this->mtime = @File::lastModified($newFullPath);\n        $this->originalFileName = $this->fileName;\n        $this->exists = true;","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/cms/classes/Lang.php#L257-L293","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before — file owned by root, web server cannot write\n$ ls -l themes/mytheme/lang/en.json\n-rw-r--r-- root root themes/mytheme/lang/en.json\n\n# after\nsudo chown www-data:www-data themes/mytheme/lang/en.json\nsudo chmod u+w themes/mytheme/lang/en.json","handlingStrategy":"validation","validationCode":"$path = $lang->getFilePath();\nif (file_exists($path) && !is_writable($path)) {\n    return back()->with('error', 'The file exists but is not writable by the web server.');\n}\nif (!is_writable(dirname($path))) {\n    return back()->with('error', 'The lang directory is not writable.');\n}\n$lang->save();","typeGuard":null,"tryCatchPattern":"try {\n    $lang->save();\n} catch (ApplicationException $e) {\n    // error_saving: log the resolved path + disk_free_space for ops triage\n    Log::error('Lang save failed', ['path' => $lang->getFilePath(), 'disk_free' => @disk_free_space(dirname($lang->getFilePath()))]);\n    throw $e;\n}","preventionTips":["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."],"tags":["filesystem","permissions","write-failure","io","lang"],"backgroundTag":"file-write-permission-denied","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}