octobercms/october · error · ApplicationException

cms::lang.cms_object.file_already_exists

Error message

cms::lang.cms_object.file_already_exists

What it means

ApplicationException thrown by `Lang::save()` when the target file already exists on disk AND the new name differs from the original (`originalFileName !== fileName`), i.e. the save is a rename onto an existing file. The check deliberately prevents silently overwriting another theme language file.

Source

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

                    ['name' => $key]
                ));
            }

            $this->$key = $value;
        }
    }

    /**
     * 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(

View on GitHub (pinned to b608633a7e)

Solutions

  1. Choose a different, unused file name for the rename.
  2. If overwriting is intended, delete or rename the existing file first, or edit the existing file instead of creating a duplicate.
  3. Pre-check with `File::exists($obj->getFilePath())` before calling save() and surface a friendly message.

Example fix

// before — rename collides with an existing file
$lang->fileName = 'en.json'; // lang/en.json already exists
$lang->save(); // throws file_already_exists

// after — verify the target is free first
$target = $theme->getPath() . '/lang/' . $lang->fileName;
if (File::exists($target) && $lang->originalFileName !== $lang->fileName) {
    throw new ApplicationException('en.json already exists — pick another name.');
}
$lang->save();
Defensive patterns

Strategy: validation

Validate before calling

use Winter\Storm\Support\Facades\File;

$target = $lang->getFilePath();
if (File::exists($target) && $lang->originalFileName !== $lang->fileName) {
    throw new ValidationException(['fileName' => 'That file name is already taken in this theme.']);
}
$lang->save();

Try / catch

try {
    $lang->save();
} catch (ApplicationException $e) {
    if (strpos($e->getMessage(), 'already exists') !== false) {
        return back()->with('error', 'Name taken — choose another file name.');
    }
    throw $e;
}

Prevention

When it happens

Trigger: Renaming a lang file in the editor to a base name that is already present in `themes/<theme>/lang/` (e.g. renaming messages.json to en.json when en.json exists); creating a 'new' file whose name collides with one on disk.

Common situations: Two similar translation files consolidated by rename; case-insensitive filesystems (macOS/Windows dev) hiding EN.json vs en.json collisions that later break on Linux; files left behind by a previous import.

Related errors


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