octobercms/october · error · ApplicationException

Unable to create directory {tempPath}

Error message

Unable to create directory {tempPath}

What it means

ThemeExport::export() stages a copy of the theme under a fresh temp_path()/oc* directory before zipping it. It throws when File::makeDirectory($tempPath) returns false, meaning the PHP process could not create a directory inside storage/temp. Since the path is uniquid-generated per run, this is an environment failure (permissions, disk space, read-only filesystem), not a name collision.

Source

Thrown at modules/cms/models/ThemeExport.php:110

        $this->attributes['theme'] = $theme;
    }

    /**
     * export
     */
    public function export($theme, $data = [])
    {
        $this->theme = $theme;
        $this->fill($data);

        try {
            $themePath = $this->theme->getPath();
            $tempPath = temp_path() . '/'.uniqid('oc');
            $zipName = uniqid('oc');
            $zipPath = temp_path().'/'.$zipName;

            if (!File::makeDirectory($tempPath)) {
                throw new ApplicationException('Unable to create directory '.$tempPath);
            }

            if (!File::makeDirectory($metaPath = $tempPath . '/meta')) {
                throw new ApplicationException('Unable to create directory '.$metaPath);
            }

            File::copy($themePath.'/theme.yaml', $tempPath.'/theme.yaml');
            File::copyDirectory($themePath.'/meta', $metaPath);

            foreach ($this->folders as $folder) {
                if (!array_key_exists($folder, $this->getFoldersOptions())) {
                    continue;
                }

                File::copyDirectory($themePath.'/'.$folder, $tempPath.'/'.$folder);
            }

            Zip::make($zipPath, $tempPath);

View on GitHub (pinned to b608633a7e)

Solutions

  1. Give the PHP user write access to storage: chown -R www-data:www-data storage then chmod -R 775 storage.
  2. Confirm writability: php artisan tinker, then is_writable(temp_path()); - must be true.
  3. Check free space and inodes (df -h, df -i) and clean up storage/temp if full.
  4. In containers, mount a writable volume at storage/ so temp_path() resolves to writable storage.

Example fix

# before: export fails - PHP cannot mkdir under storage/temp
ls -ld storage/temp   # root:root 755
sudo chown -R www-data:www-data storage && sudo chmod -R 775 storage

# after
php artisan tinker
>>> is_writable(temp_path());   // true - export succeeds
Defensive patterns

Strategy: validation

Validate before calling

$temp = temp_path();

if (!is_dir($temp) && !@mkdir($temp, 0775, true)) {
    throw new RuntimeException("{$temp} cannot be created - fix storage permissions");
}
if (!is_writable($temp)) {
    // block the export with an actionable message
}
if (disk_free_space($temp) < 100 * 1024 * 1024) {
    // block the export: low disk
}

Try / catch

try {
    $token = ThemeExport::export($theme, $data);
} catch (ApplicationException $e) {
    // message names the failing path - report storage/temp permissions,
    // then clean partially created temp_path()/oc* directories
}

Prevention

When it happens

Trigger: Triggering a theme export (backend CMS > Themes > export, which calls ThemeExport::export()) when the web-server user lacks write permission on storage/temp, the disk or quota is exhausted, or the app runs on a read-only container filesystem.

Common situations: Shared hosting where storage/ was uploaded without write permissions; Docker deploys with read-only app volumes; disk quota hit; open_basedir restrictions excluding temp_path().

Related errors


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