octobercms/october · warning · ValidationException

cms::lang.cms_object.invalid_file_extension

Error message

cms::lang.cms_object.invalid_file_extension

What it means

ValidationException thrown by `Lang::validateFileName()` when the file name's extension is not in `$allowedExtensions` — for theme lang files that list is exactly `['json']`. Theme translation files must be JSON; PHP-array or YAML translation formats from other systems are rejected here.

Source

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

    protected function validateFileName($fileName = null)
    {
        if ($fileName === null) {
            $fileName = $this->fileName;
        }

        $fileName = trim($fileName);

        if (!strlen($fileName)) {
            throw new ValidationException(['fileName' =>
                LangHelper::get('cms::lang.cms_object.file_name_required', [
                    'allowed' => implode(', ', $this->allowedExtensions),
                    'invalid' => pathinfo($fileName, PATHINFO_EXTENSION)
                ])
            ]);
        }

        if (!FileHelper::validateExtension($fileName, $this->allowedExtensions, false)) {
            throw new ValidationException(['fileName' =>
                LangHelper::get('cms::lang.cms_object.invalid_file_extension', [
                    'allowed' => implode(', ', $this->allowedExtensions),
                    'invalid' => pathinfo($fileName, PATHINFO_EXTENSION)
                ])
            ]);
        }

        if (!FileHelper::validatePath($fileName, null)) {
            throw new ValidationException(['fileName' =>
                LangHelper::get('cms::lang.cms_object.invalid_file', [
                    'name' => $fileName
                ])
            ]);
        }
    }

    /**
     * validate object

View on GitHub (pinned to b608633a7e)

Solutions

  1. Use a .json file name (e.g. 'en.json') and JSON object content.
  2. Convert PHP-array translations to JSON before importing (`json_encode(include $phpFile)`).
  3. Validate the extension client-side with the allowed list from the API response.

Example fix

// before — theme lang files are JSON only
$lang->fill(['fileName' => 'en.php', 'content' => "<?php return [];"]);

// after
$lang->fill(['fileName' => 'en.json', 'content' => '{"hello.world": "Hello"}']);
Defensive patterns

Strategy: validation

Validate before calling

$ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
if ($ext !== 'json') {
    throw new ValidationException(['fileName' => 'Theme lang files must use the .json extension.']);
}
$lang->fileName = $fileName;
$lang->save();

Try / catch

try {
    $lang->save();
} catch (Winter\Storm\Exception\ValidationException $e) {
    return back()->withErrors($e->getErrors())->withInput();
}

Prevention

When it happens

Trigger: Saving a lang object with fileName 'en.php' or 'messages.yaml'; importing translations in PHP array format from the application-level lang directory into a theme; scripts reusing file names from other CMS object types (pages use .htm).

Common situations: Migrating translations from Winter's `lang/` PHP files to theme lang files without converting; developers assuming all CMS objects share one extension; tooling that appends '.txt' to generated files.

Related errors


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