doctrine/orm · error · InvalidArgumentException

The directory "%s" is not writable.

Error message

The directory "%s" is not writable.

What it means

InvalidArgumentException from FileLockRegion::__construct() (src/Cache/Region/FileLockRegion.php:55). The lock directory exists (or was created), but PHP's is_writable() reports the process cannot write into it — FileLockRegion must create/lock/unlink files there on every READ_WRITE cache access, so it aborts construction instead of failing at first lock.

Source

Thrown at src/Cache/Region/FileLockRegion.php:55

{
    final public const LOCK_EXTENSION = 'lock';

    /**
     * @param numeric-string|int $lockLifetime
     *
     * @throws InvalidArgumentException
     */
    public function __construct(
        private readonly Region $region,
        private readonly string $directory,
        private readonly string|int $lockLifetime,
    ) {
        if (! is_dir($directory) && ! @mkdir($directory, 0775, true)) {
            throw new InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $directory));
        }

        if (! is_writable($directory)) {
            throw new InvalidArgumentException(sprintf('The directory "%s" is not writable.', $directory));
        }
    }

    private function isLocked(CacheKey $key, Lock|null $lock = null): bool
    {
        $filename = $this->getLockFileName($key);

        if (! is_file($filename)) {
            return false;
        }

        $time    = $this->getLockTime($filename);
        $content = $this->getLockContent($filename);

        if ($content === false || $time === false) {
            @unlink($filename);

            return false;

View on GitHub (pinned to d9b9ff7301)

Solutions

  1. Fix ownership/permissions: chown -R www-data:www-data /var/cache/doctrine-lock && chmod 775 /var/cache/doctrine-lock (and ensure the PHP process user matches).
  2. Have deployment create the directory as the app user (or with correct ownership) instead of root.
  3. Verify with the same user that runs PHP: sudo -u www-data test -w /var/cache/doctrine-lock.
  4. If stale root-owned lock files (*.lock) exist inside, remove them too — lock files, not just the directory, must be writable/unlinkable.

Example fix

# before: deploy script (root) created the dir, php-fpm runs as www-data
# sudo -u www-data test -w /var/cache/doctrine-lock -> fails

# after
chown -R www-data:www-data /var/cache/doctrine-lock
chmod 775 /var/cache/doctrine-lock
Defensive patterns

Strategy: validation

Validate before calling

if (! is_writable($lockRegionDirectory)) {
    throw new RuntimeException(
        sprintf('Lock dir %s not writable by %s', $lockRegionDirectory, get_current_user())
    );
}

Prevention

When it happens

Trigger: Directory owned by root or another user with no group/other write bits for the web/CLI user; ACLs denying the PHP user; SELinux/AppArmor confining writes to that path; NFS root-squash making root-owned dirs unwritable.

Common situations: Directory created by a root-run deploy script while php-fpm runs as www-data; CLI (root cron) warmed the lock dir with root-owned lock files; container images with root-owned /var directories; moving cache between hosts with preserved ownership.

Related errors


AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21). Data as JSON: /api/errors/54c52e0d0f282a96. Report an issue: GitHub.