laravel/framework · error · InvalidArgumentException

Scoped disk is missing "prefix" configuration option.

Error message

Scoped disk is missing "prefix" configuration option.

What it means

Thrown by FilesystemManager::createScopedDriver() when 'disk' is present but 'prefix' is empty. The prefix is the path namespace the scoped driver applies on top of the parent disk; an empty prefix would make the scope a no-op, so Laravel requires it explicitly.

Solutions

  1. Add a non-empty 'prefix' to the scoped disk config.
  2. If no namespace is needed, drop the scoped disk and use the parent disk directly.
  3. Use a meaningful prefix (e.g., 'thumbnails', 'backups') that matches your storage layout.
  4. Run php artisan config:clear / config:cache after editing.

Example fix

// before
'thumbnails' => [
    'driver' => 'scoped',
    'disk' => 's3',
],

// after
'thumbnails' => [
    'driver' => 'scoped',
    'disk' => 's3',
    'prefix' => 'thumbnails',
],
Defensive patterns

Strategy: validation

Validate before calling

if (empty(config("filesystems.disks.{$name}.prefix"))) {
    throw new InvalidArgumentException("Scoped disk [{$name}] missing 'prefix' option.");
}

Type guard

function scopedDiskHasPrefix(string $name): bool {
    return ! empty(config("filesystems.disks.{$name}.prefix"));
}

Try / catch

try {
    Storage::disk($name);
} catch (\InvalidArgumentException $e) {
    report($e);
}

Prevention

When it happens

Trigger: Defining a scoped disk with 'driver' => 'scoped' and 'disk' set, but omitting 'prefix' or leaving it as an empty string.

Common situations: Copy-paste config missing the prefix line; intent was to alias the parent disk without a namespace (not supported — use the parent directly); typo in 'prefix' key (e.g., 'path').

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/d3c3d6f041d9acd2. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Filesystem/FilesystemManager.php:303

        }

        return Arr::except($config, ['token']);
    }

    /**
     * Create a scoped driver.
     *
     * @param  array  $config
     * @return \Illuminate\Contracts\Filesystem\Filesystem
     *
     * @throws \InvalidArgumentException
     */
    public function createScopedDriver(array $config)
    {
        if (empty($config['disk'])) {
            throw new InvalidArgumentException('Scoped disk is missing "disk" configuration option.');
        } elseif (empty($config['prefix'])) {
            throw new InvalidArgumentException('Scoped disk is missing "prefix" configuration option.');
        }

        return $this->build(tap(
            is_string($config['disk']) ? $this->getConfig($config['disk']) : $config['disk'],
            function (&$parent) use ($config) {
                if (empty($parent['prefix'])) {
                    $parent['prefix'] = $config['prefix'];
                } else {
                    $separator = $parent['directory_separator'] ?? DIRECTORY_SEPARATOR;

                    $parentPrefix = rtrim($parent['prefix'], $separator);
                    $scopedPrefix = ltrim($config['prefix'], $separator);

                    $parent['prefix'] = "{$parentPrefix}{$separator}{$scopedPrefix}";
                }

                if (isset($config['visibility'])) {
                    $parent['visibility'] = $config['visibility'];

View on GitHub (pinned to e0f6eb3518)