octobercms/october · error · ApplicationException

cms::lang.cms_object.error_creating_directory

Error message

cms::lang.cms_object.error_creating_directory

What it means

ApplicationException thrown by `Lang::save()` when `File::makeDirectory()` fails to create the theme's `lang/` directory. This happens on the first lang-file save in a theme that has no lang/ folder yet, and almost always means the web server user lacks write permission on the theme directory (or the path is blocked by open_basedir / a read-only mount).

Source

Thrown at modules/cms/classes/Lang.php:266

     * save the object to the disk
     */
    public function save(array $options = [])
    {
        $this->validateFileName();

        $fullPath = $this->getFilePath();

        if (File::isFile($fullPath) && $this->originalFileName !== $this->fileName) {
            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)) {

View on GitHub (pinned to b608633a7e)

Solutions

  1. Give the web server user write access: `chown -R www-data:www-data themes/<theme>` (or group-write with the right group).
  2. Verify the path is inside allowed open_basedir limits and the filesystem is not mounted read-only.
  3. Pre-create `themes/<theme>/lang/` in your deployment with correct ownership so makeDirectory is never needed at runtime.

Example fix

# before — theme dir not writable by PHP
$ ls -ld themes/mytheme
drwxr-xr-x root root themes/mytheme

# after — grant web server user ownership
sudo chown -R www-data:www-data themes/mytheme
sudo chmod -R u+rwX themes/mytheme
Defensive patterns

Strategy: validation

Validate before calling

$dir = $theme->getPath() . '/' . $lang->dirName;
if (!is_dir($dir) && !is_writable($theme->getPath())) {
    return back()->with('error', 'Theme directory is not writable — fix permissions first.');
}
$lang->save();

Try / catch

try {
    $lang->save();
} catch (ApplicationException $e) {
    // error_creating_directory / error_saving: surface an ops-friendly message
    report($e);
    return response()->json(['error' => 'Server cannot write to the theme directory. Contact the administrator.'], 500);
}

Prevention

When it happens

Trigger: First save of a theme lang file on a server where `themes/<theme>/` is owned by root or lacks write permission for PHP; deploying themes via git as root so the directory is not writable by the www-data user; open_basedir restrictions excluding the theme path.

Common situations: Production servers with read-only theme deploys; permissions lost after server migration or restore; containerized deployments with wrong volume ownership; SELinux denying directory creation.

Related errors


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